GithubHelp home page GithubHelp logo

kotlin / kotlinx-atomicfu Goto Github PK

View Code? Open in Web Editor NEW
840.0 34.0 56.0 1.38 MB

The idiomatic way to use atomic operations in Kotlin

License: Other

Kotlin 99.64% Shell 0.22% Java 0.14%
kotlinx atomic kotlin

kotlinx-atomicfu's People

Contributors

alexeytsvetkov avatar cy6ergn0m avatar dumanskaia avatar e5l avatar elizarov avatar erokhins avatar fenstonsingel avatar forrestpangborn avatar fxshlein avatar h0tk3y avatar igoriakovlev avatar ilgonmic avatar ilmirus avatar kirilltim avatar linroid avatar lion7 avatar merfemor avatar mvicsokolova avatar nikitabobko avatar pavelpunegov avatar qwwdfsad avatar rock3r avatar sbogolepov avatar sellmair avatar semoro avatar skuzmich avatar sokolovamaria avatar stasjas avatar tapchicoma avatar woainikk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kotlinx-atomicfu's Issues

Source set 'commonMain' of project '<project name>' is part of several compilations [debug, release, main]

I added the kotlinx-atomicfu plugin to my multiplatform project. As soon as I did that I get the following error:

Source set 'commonMain' of project '<project name>' is part of several compilations [debug, release, main]

Here is my entire build.gradle.kts:

plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.multiplatform")
    id("kotlinx-atomicfu")
}

android {
    compileSdkVersion(AndroidConfig.compileSdkVersion)

    defaultConfig {
        minSdkVersion(AndroidConfig.minSdkVersion)
        targetSdkVersion(AndroidConfig.targetSdkVersion)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    implementation(Libs.kotlin.stdlib.jvm)
    implementation(Libs.androidx.annotation)
    implementation(Libs.androidx.browser)
    implementation(Libs.rally.kinject.jvm)
    implementation(Libs.rally.kinject.jvm)
    implementation(Libs.kotlinx.coroutines.android)
}

kotlin {
    android()

    @Suppress("UNUSED_VARIABLE")
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(Libs.kotlin.stdlib.common)
                implementation(Libs.rally.kinject.common)
                implementation(Libs.rally.store.common)
                implementation(Libs.rally.disposable.common)
                implementation(Libs.kotlinx.coroutines.common)
            }
        }

        val commonTest by getting {
            dependencies {
                for (lib in Libs.kotlin.test.common) {
                    implementation(lib)
                }
            }
        }
    }
}

Atomicfu plugin adds common dependencies to platform modules

Adding common dependency to a native module causes Gradle plugin to complain about it for every module. In ktor, it generates a huge number of warnings so one wouldn't be able to discover actual problems.

A compileOnly dependency is used in the Kotlin/Native target 'linuxX64':
Compilation: main

Dependencies:
org.jetbrains.kotlinx:atomicfu-common:0.12.9

Such dependencies are not applicable for Kotlin/Native, consider changing the dependency type to 'implementation' or 'api'.

Fragile JS transformer

AtomicFU js transformer is fragile. It works for kotlinx.coroutines but it is not generally applicable to wider range of libraries. Here is a snippet of produced JS code:

(function(root, factory) {
  if (typeof define === 'function' && define.amd) 
    define(['exports', 'kotlin'], factory);
  else if (typeof exports === 'object') 
    factory(module.exports, require('kotlin'));
  else {
    if (typeof kotlin === 'undefined') {
      throw new Error("Error loading module 'kotlinx-coroutines-core'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'kotlinx-coroutines-core'.");
    }
    if (typeof this['kotlinx-atomicfu'] === 'undefined') {
    }
    root['kotlinx-coroutines-core'] = factory(typeof this['kotlinx-coroutines-core'] === 'undefined' ? {} : this['kotlinx-coroutines-core'], kotlin);
  }
}(this, function(_, Kotlin, $module$kotlinx_atomicfu) {
  'use strict';
...
  var atomic;
  var atomic_0;
....
  $$importsForInline$$['kotlinx-atomicfu'] = $module$kotlinx_atomicfu;

Things that should be fixed:

  1. if (typeof this['kotlinx-atomicfu'] === 'undefined') { ... } should be completely removed (not just it body), while maintaining line-numbers (fill with appropriate number of blank lines or comments)
  2. function(_, Kotlin, $module$kotlinx_atomicfu) { ... header should be corrected, its $module$kotlinx_atomicfu parameters shall be removed at the appropriate position (note, that it may receive additional modules after kotlinx_atomicfu)
  3. var atomic; and var atmoic_0; shall be removed completely (replaced with a blank like), not just their right-hand side.
  4. $$importsForInline$$['kotlinx-atomicfu'] = $module$kotlinx_atomicfu; line shall be replaced with a blank like (if present).

Gradle plugin: detect Kotlin platform and automatically add dependencies

Currently readme on Gradle says that you need to add the following dependencies to your gradle file:

dependencies {
    compileOnly "org.jetbrains.kotlinx:atomicfu:$atomicfu_version"
    testRuntime "org.jetbrains.kotlinx:atomicfu:$atomicfu_version"
}

This should not be needed. Plugin shall do it automatically on JVM. Moreover, plugin shall automatically detect what Kotlin platform is used (based on the Kotlin plugin that is applied) and also add appropriate dependencies for Kotlin/JS and Kotlin/Native.

Support multi-threaded atomics on Kotlin/Native

Kotlin/Native implementation should be rewritten on top of native-specific konan.worker.AtomicReference class so that atomicfu-based code can be compiled into multi-threaded Kotlin/Native code.

Gradle 5.4.1

When will this move to latest gradle and latest kotlin
5.4.1, 1.3.31 ?

What does the Incubator status means for AtomicFu?

Hi there, first of all thanks for this library!

However I'm confused by its current status. The readme shows this project as Incubator, which is defined on jetbrains.com as considered experimental, not mature enough, or lacking in some manner or release quality such testing and supporting documentation.

We are writing an open source library, and worry that we shouldn't use AtomicFu in our libraries, because of the uncertainty around its maturity and safety in production. But I know that kotlin.coroutines relies on AtomicFu, and that coroutines are no more considered experimental, having being added to the kotlin stdlib.

  • Does this mean you consider AtomicFu safe for production?
  • Could you share the reasons behind marking this project as Incubator? Is it just because of an incomplete supporting documentation, or is there another reason?

Gradle transformJvmMainAtomicfu failed when using atomic() in companion obj

Caused by: java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 0
        at org.objectweb.asm.Frame.a(Unknown Source)
        at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
        at org.objectweb.asm.tree.MethodNode.accept(Unknown Source)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.visitEnd(AtomicFUTransformer.kt:611)
        at org.objectweb.asm.ClassReader.b(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transformFile(AtomicFUTransformer.kt:237)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transform(AtomicFUTransformer.kt:172)
        at kotlinx.atomicfu.plugin.gradle.AtomicFUTransformTask.transform(AtomicFUGradlePlugin.kt:387)

This works fine

class Bot( ... ) {
    private val count = atomic<Int>(0)

    val id = count.getAndUpdate { it + 1 }
}

But this doesn't work

class Bot( ... ){
    val id = count.getAndUpdate { it + 1 }

    companion object {
      private val count = atomic<Int>(0)
    }
}

And after I removed private, I got a new exception Unsupported return within atomic operation

AtomicFUTransformerJS incorrect transform for cases where `this` is used inside scope

It seems that in some cases JS transformation may lead to the deadlock, or to be specific infinite while(true) when using kotlin.coroutines.sync.Mutex (both 0.26.0 version with Kotlin 1.2 and EAP version with Kotlin 1.3 in JavaScript).

Example project here: https://github.com/ptmt/kotlinjsplayground/blob/master/src/main/kotlin/MutexCase.kt)

In particular, this line of code doesn't work as expected:
https://github.com/Kotlin/kotlinx.coroutines/blob/4cc0e294b39ae0f38cafd49187f399b0ecc2e615/common/kotlinx-coroutines-core-common/src/sync/Mutex.kt#L472

(affected as MutexImpl)._state.compareAndSet(this@UnlockOp, update)

It gets compiled into following JavaScript:

(somewhere inside kotlinx-coroutines-core.js)

(function(scope) {
    return (Kotlin.isType(tmp$ = affected, MutexImpl) ? tmp$ : throwCCE())._state_0 === this ? function() {
        (Kotlin.isType(tmp$ = affected, MutexImpl) ? tmp$ : throwCCE())._state_0 = update;
        return true;
    }() : false
})(this);

(there is also some unnecessary double-assignment but that's not the point)

As we can see affected is being compared with the wrong this, because we have a closure here. I believe it should be replaced with scope. As far as I understand it's happening here:

https://github.com/Kotlin/kotlinx.atomicfu/blob/145542d596c4767dc2bec85551b4e82c2eb7b38b/atomicfu-transformer/src/main/kotlin/kotlinx/atomicfu/transformer/AtomicFUTransformerJS.kt#L208-L212

I'd contribute a PR by myself, but I'm afraid that writing proper tests would take much longer than fix itself.

Use atomics with delegates?

Something like this?

inline operator fun <T> AtomicRef<T>.getValue(obj: Any, property: KProperty<Any?>): T = this.value
inline operator fun <T> AtomicRef<T>.setValue(obj: Any, property: KProperty<Any?>, value: T) = run { this.value = value }

inline operator fun AtomicBoolean.getValue(obj: Any, property: KProperty<Any?>): Boolean = this.value
inline operator fun AtomicBoolean.setValue(obj: Any, property: KProperty<Any?>, value: Boolean) = run { this.value = value }

inline operator fun AtomicInt.getValue(obj: Any, property: KProperty<Any?>): Int = this.value
inline operator fun AtomicInt.setValue(obj: Any, property: KProperty<Any?>, value: Int) = run { this.value = value }

inline operator fun AtomicLong.getValue(obj: Any, property: KProperty<Any?>): Long = this.value
inline operator fun AtomicLong.setValue(obj: Any, property: KProperty<Any?>, value: Long) = run { this.value = value }

Sometimes you just need to update and retrieve the .value property, in those cases, this would be nice since you could use the atomic as a plain property.

0.14.x missing from maven central

Hello! I initially couldn't figure out why I couldn't resolve the latest coroutines version of atomicfu in my project, and then I realized it was because I was only pointing at mavenCentral() in my dependencies list. Re-adding jcenter() fixed it, but it'd be great to see atomicfu back up on mavenCentral().

SynchronizedObject

We need common SynchronizedObject with the following common API:

public expect open class SynchronizedObject()
public expect inline fun <T> synchronized(lock: SynchronizedObject, block: () -> T): T

On both JVM and JS this SynchronizedObject typealises to Any. On JVM synchronized maps to JVM synchronized, while on JS it simply calls block().

On native it need to be implemented carefully, so that it reused a pool of pthread mutexes for heavy-weight synchronization in a way that requires no resource management for uses of SynchronizedObject.

Note, that on Native this primitive will by thread-safe only if all the fields that are protected by SynchronizedObject are also atomic. This limitation will be further addressed by a separate issue.

Transformation failure in objects

getAndUpdate Seems to fail when the parent class is an object:

object Example {
    private val atomic = atomic("test")

    fun update() {
        atomic.getAndUpdate { "$it !" }
    }
}

Results in the following compilation error:

Failed to transform: java.lang.ArrayIndexOutOfBoundsException: -1
java.lang.ArrayIndexOutOfBoundsException: -1
        at org.objectweb.asm.Frame.getConcreteOutputType(Frame.java:1139)
        at org.objectweb.asm.Frame.merge(Frame.java:1184)
        at org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1610)
        at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1546)
        at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:767)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.visitEnd(AtomicFUTransformer.kt:616)
        at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1288)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:688)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:400)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transformFile(AtomicFUTransformer.kt:238)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transform(AtomicFUTransformer.kt:172)
        at kotlinx.atomicfu.plugin.gradle.AtomicFUTransformTask.transform(AtomicFUGradlePlugin.kt:406)

Changing the declaration to class will compile successfully.

This seems to have been reported before in #94 as a problem with companion objects, which was closed but never resolved.

Kotlin Version: 1.3.61
atomicfu version: 0.14.1

"getAndUpdate" does not work with atomic arrays

It seems that the following code does not work:

val a = atomicArrayOfNulls<Any?>(size)
a[i].getAndUpdate{ ... }

It fails with an exception like this:

Semaphore.kt: kotlinx.coroutines.sync.SemaphoreSegment::getAndUpdate: Failed to transform: java.lang.ClassCastException: org.objectweb.asm.tree.VarInsnNode cannot be cast to org.objectweb.asm.tree.MethodInsnNode
java.lang.ClassCastException: org.objectweb.asm.tree.VarInsnNode cannot be cast to org.objectweb.asm.tree.MethodInsnNode
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.fixupInvokeVirtual(AtomicFUTransformer.kt:630)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.fixupLoadedAtomicVar(AtomicFUTransformer.kt:752)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.transform(AtomicFUTransformer.kt:944)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.visitEnd(AtomicFUTransformer.kt:551)
        at org.objectweb.asm.ClassReader.b(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at org.objectweb.asm.ClassReader.accept(Unknown Source)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transformFile(AtomicFUTransformer.kt:204)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transform(AtomicFUTransformer.kt:160)
        at kotlinx.atomicfu.plugin.gradle.AtomicFUTransformTask.transform(AtomicFUGradlePlugin.kt:388)
        . . .

Support compileOnly dependency

Failed to compile a project with compileOnly dependency:
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.0-b07'.

As workaround configurate atomicfu in afterEvaluate section.

Support top-level atomic vals

The following example code:

import kotlinx.atomicfu.*

private val a = atomic(0)

fun main(args: Array<String>) {
    a.incrementAndGet()
    println(a.value)
}

Produces the following errors during transformation:

Main.kt:6: MainKt::main: standalone invocation of kotlinx.atomicfu.AtomicInt::incrementAndGet that was not traced to previous field load
Main.kt:7: MainKt::main: standalone invocation of kotlinx.atomicfu.AtomicInt::getValue that was not traced to previous field load
Main.kt: MainKt::<clinit>: factory kotlinx.atomicfu.AtomicFU::atomic is used outside of constructor
Main.kt: MainKt::<clinit>: Failed to transform: kotlinx.atomicfu.transformer.AbortTransform: Last instruction in <clinit> shall be RETURN

We should support the use of atomic on the top level

More user-friendly Gradle plugin

Current usage of Gradle plugin is quite verbose. As explained in README it takes a lot of steps that you need to copy-paste into your gradle project file:

def CLASSES_POST_ATOMICFU = file("$buildDir/classes-post-atomicfu/main")

atomicFU {
    inputFiles = sourceSets.main.output.classesDirs
    outputDir = CLASSES_POST_ATOMICFU
    classPath = sourceSets.main.runtimeClasspath
    variant = "FU" // "VH" to use Java 9 VarHandle, "BOTH" to produce multi-version code
}

atomicFU.dependsOn compileKotlin
testClasses.dependsOn atomicFU
jar.dependsOn atomicFU

jar {
    mainSpec.sourcePaths.clear() // hack to clear existing paths
    from files(CLASSES_POST_ATOMICFU, sourceSets.main.output.resourcesDir)
}

While we'd like to continue supporting this syntax with explicit specification of inputFiles, outputDir and classPath for backwards compatibility, we'd like to be able to have a completely new default behavior, so that just doing apply plugin: 'kotlinx-atomicfu' does all the magic and configures automatic transformation for all source sets.

Support AtomicBoolean

val x = atomic(false) should be efficiently supported with native Boolean type support.

No size in atomic arrays

No size getter in AtomicArray and array field is private:

public class AtomicArray<T> internal constructor(size: Int) {
    private val array = Array(size) { atomic<T?>(null) }

    @JsName("get\$atomicfu")
    public operator fun get(index: Int): AtomicRef<T?> = array[index]
}

Support delegation properties

As atomic document says to leak atomic values to public use:

val _pref = atomic(0L)
var pref : Long
    get() = _pref.value
    set(value) { _pref.value = value }

so I think it's possible to have something like:

val pref by atomicVar(0L)
val pref by atomicVal(0L)

this::pref.atomic.value = 10

Custom format for Trace

This is a potential future enhancement.

Support custom tracing format using the following DSL:

val trace = Trace { index, text ->
   // can define custom transformation to string instead of default one below:
   "$index: [${Thread.currentThread().name}] $text" 
}

JVM transform task fails on kotlinx.coroutines

Execution failed for task ':kotlinx-coroutines-core:transformJvmMainAtomicfu'.

java.lang.ClassNotFoundException: kotlinx.coroutines.EventLoopImplBase$DelayedTaskQueue

Stacktrace:

Caused by: java.lang.ClassNotFoundException: kotlinx.coroutines.EventLoopImplBase$DelayedTaskQueue
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$CW.getCommonSuperClass(AtomicFUTransformer.kt:1165)
        at org.objectweb.asm.SymbolTable.addMergedType(SymbolTable.java:1200)
        at org.objectweb.asm.Frame.merge(Frame.java:1299)
        at org.objectweb.asm.Frame.merge(Frame.java:1244)
        at org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1610)
        at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1546)
        at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:767)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer$TransformerMV.visitEnd(AtomicFUTransformer.kt:610)
        at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1288)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:688)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:400)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transformFile(AtomicFUTransformer.kt:237)
        at kotlinx.atomicfu.transformer.AtomicFUTransformer.transform(AtomicFUTransformer.kt:172)
        at kotlinx.atomicfu.plugin.gradle.AtomicFUTransformTask.transform(AtomicFUGradlePlugin.kt:406)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)

broken publish to npm, from version 0.12.0

Apparently all versions from version 0.12.0 and later has broken publishing to npm:
only package.json and README.md are present in kotlinx-atomicfu subdirectory in node_modules, after installing it with

npm i kotlinx-atomicfu

Add README section explaining differences from Java Atomics

It would be helpful to have a README section comparing atomicfu vs Java Atomics. The current readme states:

Code it like AtomicReference/Int/Long, but run it in production efficiently as AtomicXxxFieldUpdater on Kotlin/JVM and as plain unboxed values on Kotlin/JS.

It would be helpful to have more information on why AtomicXxxFieldUpdater is more efficient then Java Atomics on Kotlin/JVM. Also any other differences to consider when choosing to use atomicfu over Java Atomics when building a Kotlin/JVM project

Prohibit to use atomicfu for public API (public & protected)

The ideal solution is providing custom checks for frontend.
Harder to implement since it requires a new integration, but will provide the best DX -- early error, including inside IDE.

Acceptable solution -- report diagnostic from the backend.
Simpler to implement, but likely still requires to extend current API, anyway it's better than crash the compiler or a user application.

Gradle plugin breaks Kotlin/Native tests compilation

Hi,

While trying to migrate a project to the new multiplatform plugin I came across a bug in the gradle plugin that makes the compiling/linking of K/N tests impossible. I fiddled with it a bit and found that the plugin modify the linker options and remove the .klib of the project, making the compilation fail with a lot of unresolved reference

This bug is fully reproducible, simply create a new multiplatform project with IDEA, it works, add the atomicfu plugin, now it fails to compile K/N tests. I also found that the artifact published on NPM is now empty, is it intentional (as the transformation is supposed to remove any reference to atomicFU)?

I attached a sample project that triggers the bug

Thank you very much for your time!

reproBug.zip

JVM transformation: unsupported branching/control for not-null assertion

class Example {
    private val a = atomic<Any?>(null)
    private val something: Any? = "here it is"

    fun f() {
        a.compareAndSet(something!!, null)
    }
Example::f: Unsupported branching/control within atomic operation
Example::f: standalone invocation of kotlinx.atomicfu.AtomicRef::compareAndSet that was not traced to previous field load

Workarounds:

  • remove !! assertion
  • extract expected value into a new variable (but keep !! assertion)

Version: 0.11.10-eap13
Kotlin: 1.3.0-rc-131

Maven central publication

No atomicfu artifacts published at maven central: the latest published version is 0.11.12. This is important since ktor users is unable to use ktor without specifying additional repositories.

Also notice that the latest release on github is in draft state

NPE on JS plugin on 0.12.x

I've got an NPE inside the JS plugin for in this code.
Actual error obtained with gradle --stacktrace build:

Caused by: java.lang.NullPointerException
        at org.mozilla.javascript.ast.ParenthesizedExpression.visit(ParenthesizedExpression.java:75)
        at org.mozilla.javascript.ast.FunctionCall.visit(FunctionCall.java:158)
        at org.mozilla.javascript.ast.ExpressionStatement.visit(ExpressionStatement.java:120)
        at org.mozilla.javascript.ast.Block.visit(Block.java:61)
        at org.mozilla.javascript.ast.FunctionNode.visit(FunctionNode.java:442)
        at kotlinx.atomicfu.transformer.AtomicFUTransformerJS$AtomicOperationsInliner.visit(AtomicFUTransformerJS.kt:314)

The error is thrown both on 0.12.0 and 0.12.1. If I comment out js part, everything works fine.

DCE for user-defined extensions in atomicfu

Consider the following user-defined extension: private inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true)

Currently, the postprocessor retains the original method in the bytecode. While it is okay for the Kotlin compiler to do so, it is not the case for atomicfu that should remove every trace of itself after post-processing. Otherwise, resulting classfiles are polluted with symbols that are missing from the classpath (and it may trigger warnings like Kotlin/kotlinx.coroutines#1155).

Also, note that not only extensions but their access-bridges should be removed.

Support atomic arrays

Support AtomicArray<T> class. It should be conceptually similar to Array<AtomicRef<T>>. The following snippet provides a glimpse of proposed API:

val a = AtomicArray<T>(size) // similar to Array constructor

val x = a[i].value // read value
a[i].value = x // set value
a[i].compareAndSet(expect, update) // do atomic operations

In FU mode it should simply map onto AtomicReferenceArray and its operations, but in VH mode it shall be efficiently implement via a simple array reference with VarHandle to perform atomic operations on elements.

In addition to AtomicArray, support for AtomicBooleanArray, AtomicIntArray, and AtomicLongArray shall be provided as well.

Is there the possibility to favour writers?

I have a classic consumer-producer problem with many read and few, but crucial, writes.

What fairness policies does this library uses? Can you tweak them?

My usecase is an MutableMap used as cache. Recovering stuff from server is expensive so I'd like to minimize it as much as possible.
Of course if there is a write pending, I want no new reads to happens because I may save some from calling the server!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.