1*68017707SAndroid Build Coastguard Worker# AtomicFU 2*68017707SAndroid Build Coastguard Worker 3*68017707SAndroid Build Coastguard Worker[](https://kotlinlang.org/docs/components-stability.html) 4*68017707SAndroid Build Coastguard Worker[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) 5*68017707SAndroid Build Coastguard Worker[](https://www.apache.org/licenses/LICENSE-2.0) 6*68017707SAndroid Build Coastguard Worker[](https://search.maven.org/artifact/org.jetbrains.kotlinx/atomicfu/0.23.1/pom) 7*68017707SAndroid Build Coastguard Worker 8*68017707SAndroid Build Coastguard Worker>Note on Beta status: the plugin is in its active development phase and changes from release to release. 9*68017707SAndroid Build Coastguard Worker>We do provide a compatibility of atomicfu-transformed artifacts between releases, but we do not provide 10*68017707SAndroid Build Coastguard Worker>strict compatibility guarantees on plugin API and its general stability between Kotlin versions. 11*68017707SAndroid Build Coastguard Worker 12*68017707SAndroid Build Coastguard Worker**Atomicfu** is a multiplatform library that provides the idiomatic and efficient way of using atomic operations in Kotlin. 13*68017707SAndroid Build Coastguard Worker 14*68017707SAndroid Build Coastguard Worker## Table of contents 15*68017707SAndroid Build Coastguard Worker- [Requirements](#requirements) 16*68017707SAndroid Build Coastguard Worker- [Features](#features) 17*68017707SAndroid Build Coastguard Worker- [Example](#example) 18*68017707SAndroid Build Coastguard Worker- [Quickstart](#quickstart) 19*68017707SAndroid Build Coastguard Worker - [Apply plugin to a project](#apply-plugin) 20*68017707SAndroid Build Coastguard Worker - [Gradle configuration](#gradle-configuration) 21*68017707SAndroid Build Coastguard Worker - [Maven configuration](#maven-configuration) 22*68017707SAndroid Build Coastguard Worker- [Usage constraints](#usage-constraints) 23*68017707SAndroid Build Coastguard Worker- [Transformation modes](#transformation-modes) 24*68017707SAndroid Build Coastguard Worker - [Atomicfu compiler plugin](#atomicfu-compiler-plugin) 25*68017707SAndroid Build Coastguard Worker- [Options for post-compilation transformation](#options-for-post-compilation-transformation) 26*68017707SAndroid Build Coastguard Worker - [JVM options](#jvm-options) 27*68017707SAndroid Build Coastguard Worker - [JS options](#js-options) 28*68017707SAndroid Build Coastguard Worker- [More features](#more-features) 29*68017707SAndroid Build Coastguard Worker - [Arrays of atomic values](#arrays-of-atomic-values) 30*68017707SAndroid Build Coastguard Worker - [User-defined extensions on atomics](#user-defined-extensions-on-atomics) 31*68017707SAndroid Build Coastguard Worker - [Locks](#locks) 32*68017707SAndroid Build Coastguard Worker - [Tracing operations](#tracing-operations) 33*68017707SAndroid Build Coastguard Worker- [Kotlin/Native support](#kotlin-native-support) 34*68017707SAndroid Build Coastguard Worker 35*68017707SAndroid Build Coastguard Worker## Requirements 36*68017707SAndroid Build Coastguard Worker 37*68017707SAndroid Build Coastguard WorkerStarting from version `0.23.1` of the library your project is required to use: 38*68017707SAndroid Build Coastguard Worker 39*68017707SAndroid Build Coastguard Worker* Gradle `7.0` or newer 40*68017707SAndroid Build Coastguard Worker 41*68017707SAndroid Build Coastguard Worker* Kotlin `1.7.0` or newer 42*68017707SAndroid Build Coastguard Worker 43*68017707SAndroid Build Coastguard Worker## Features 44*68017707SAndroid Build Coastguard Worker 45*68017707SAndroid Build Coastguard Worker* Complete multiplatform support: JVM, Native, JS and Wasm (since Kotlin 1.9.20). 46*68017707SAndroid Build Coastguard Worker* Code it like a boxed value `atomic(0)`, but run it in production efficiently: 47*68017707SAndroid Build Coastguard Worker * For **JVM**: an atomic value is represented as a plain value atomically updated with `java.util.concurrent.atomic.AtomicXxxFieldUpdater` from the Java standard library. 48*68017707SAndroid Build Coastguard Worker * For **JS**: an atomic value is represented as a plain value. 49*68017707SAndroid Build Coastguard Worker * For **Native**: atomic operations are delegated to Kotlin/Native atomic intrinsics. 50*68017707SAndroid Build Coastguard Worker * For **Wasm**: an atomic value is not transformed, it remains boxed, and `kotlinx-atomicfu` library is used as a runtime dependency. 51*68017707SAndroid Build Coastguard Worker* Use Kotlin-specific extensions (e.g. inline `loop`, `update`, `updateAndGet` functions). 52*68017707SAndroid Build Coastguard Worker* Use atomic arrays, user-defined extensions on atomics and locks (see [more features](#more-features)). 53*68017707SAndroid Build Coastguard Worker* [Tracing operations](#tracing-operations) for debugging. 54*68017707SAndroid Build Coastguard Worker 55*68017707SAndroid Build Coastguard Worker## Example 56*68017707SAndroid Build Coastguard Worker 57*68017707SAndroid Build Coastguard WorkerLet us declare a `top` variable for a lock-free stack implementation: 58*68017707SAndroid Build Coastguard Worker 59*68017707SAndroid Build Coastguard Worker```kotlin 60*68017707SAndroid Build Coastguard Workerimport kotlinx.atomicfu.* // import top-level functions from kotlinx.atomicfu 61*68017707SAndroid Build Coastguard Worker 62*68017707SAndroid Build Coastguard Workerprivate val top = atomic<Node?>(null) 63*68017707SAndroid Build Coastguard Worker``` 64*68017707SAndroid Build Coastguard Worker 65*68017707SAndroid Build Coastguard WorkerUse `top.value` to perform volatile reads and writes: 66*68017707SAndroid Build Coastguard Worker 67*68017707SAndroid Build Coastguard Worker```kotlin 68*68017707SAndroid Build Coastguard Workerfun isEmpty() = top.value == null // volatile read 69*68017707SAndroid Build Coastguard Workerfun clear() { top.value = null } // volatile write 70*68017707SAndroid Build Coastguard Worker``` 71*68017707SAndroid Build Coastguard Worker 72*68017707SAndroid Build Coastguard WorkerUse `compareAndSet` function directly: 73*68017707SAndroid Build Coastguard Worker 74*68017707SAndroid Build Coastguard Worker```kotlin 75*68017707SAndroid Build Coastguard Workerif (top.compareAndSet(expect, update)) ... 76*68017707SAndroid Build Coastguard Worker``` 77*68017707SAndroid Build Coastguard Worker 78*68017707SAndroid Build Coastguard WorkerUse higher-level looping primitives (inline extensions), for example: 79*68017707SAndroid Build Coastguard Worker 80*68017707SAndroid Build Coastguard Worker```kotlin 81*68017707SAndroid Build Coastguard Workertop.loop { cur -> // while(true) loop that volatile-reads current value 82*68017707SAndroid Build Coastguard Worker ... 83*68017707SAndroid Build Coastguard Worker} 84*68017707SAndroid Build Coastguard Worker``` 85*68017707SAndroid Build Coastguard Worker 86*68017707SAndroid Build Coastguard WorkerUse high-level `update`, `updateAndGet`, and `getAndUpdate`, 87*68017707SAndroid Build Coastguard Workerwhen possible, for idiomatic lock-free code, for example: 88*68017707SAndroid Build Coastguard Worker 89*68017707SAndroid Build Coastguard Worker```kotlin 90*68017707SAndroid Build Coastguard Workerfun push(v: Value) = top.update { cur -> Node(v, cur) } 91*68017707SAndroid Build Coastguard Workerfun pop(): Value? = top.getAndUpdate { cur -> cur?.next } ?.value 92*68017707SAndroid Build Coastguard Worker``` 93*68017707SAndroid Build Coastguard Worker 94*68017707SAndroid Build Coastguard WorkerDeclare atomic integers and longs using type inference: 95*68017707SAndroid Build Coastguard Worker 96*68017707SAndroid Build Coastguard Worker```kotlin 97*68017707SAndroid Build Coastguard Workerval myInt = atomic(0) // note: integer initial value 98*68017707SAndroid Build Coastguard Workerval myLong = atomic(0L) // note: long initial value 99*68017707SAndroid Build Coastguard Worker``` 100*68017707SAndroid Build Coastguard Worker 101*68017707SAndroid Build Coastguard WorkerInteger and long atomics provide all the usual `getAndIncrement`, `incrementAndGet`, `getAndAdd`, `addAndGet`, and etc 102*68017707SAndroid Build Coastguard Workeroperations. They can be also atomically modified via `+=` and `-=` operators. 103*68017707SAndroid Build Coastguard Worker 104*68017707SAndroid Build Coastguard Worker## Quickstart 105*68017707SAndroid Build Coastguard Worker### Apply plugin 106*68017707SAndroid Build Coastguard Worker#### Gradle configuration 107*68017707SAndroid Build Coastguard Worker 108*68017707SAndroid Build Coastguard WorkerGradle configuration is supported for all platforms, minimal version is Gradle 6.8. 109*68017707SAndroid Build Coastguard Worker 110*68017707SAndroid Build Coastguard WorkerIn top-level build file: 111*68017707SAndroid Build Coastguard Worker 112*68017707SAndroid Build Coastguard Worker<details open> 113*68017707SAndroid Build Coastguard Worker<summary>Kotlin</summary> 114*68017707SAndroid Build Coastguard Worker 115*68017707SAndroid Build Coastguard Worker```kotlin 116*68017707SAndroid Build Coastguard Workerbuildscript { 117*68017707SAndroid Build Coastguard Worker repositories { 118*68017707SAndroid Build Coastguard Worker mavenCentral() 119*68017707SAndroid Build Coastguard Worker } 120*68017707SAndroid Build Coastguard Worker 121*68017707SAndroid Build Coastguard Worker dependencies { 122*68017707SAndroid Build Coastguard Worker classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.23.1") 123*68017707SAndroid Build Coastguard Worker } 124*68017707SAndroid Build Coastguard Worker} 125*68017707SAndroid Build Coastguard Worker 126*68017707SAndroid Build Coastguard Workerapply(plugin = "kotlinx-atomicfu") 127*68017707SAndroid Build Coastguard Worker``` 128*68017707SAndroid Build Coastguard Worker</details> 129*68017707SAndroid Build Coastguard Worker 130*68017707SAndroid Build Coastguard Worker<details> 131*68017707SAndroid Build Coastguard Worker<summary>Groovy</summary> 132*68017707SAndroid Build Coastguard Worker 133*68017707SAndroid Build Coastguard Worker```groovy 134*68017707SAndroid Build Coastguard Workerbuildscript { 135*68017707SAndroid Build Coastguard Worker repositories { 136*68017707SAndroid Build Coastguard Worker mavenCentral() 137*68017707SAndroid Build Coastguard Worker } 138*68017707SAndroid Build Coastguard Worker dependencies { 139*68017707SAndroid Build Coastguard Worker classpath 'org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.23.1' 140*68017707SAndroid Build Coastguard Worker } 141*68017707SAndroid Build Coastguard Worker} 142*68017707SAndroid Build Coastguard Worker 143*68017707SAndroid Build Coastguard Workerapply plugin: 'kotlinx-atomicfu' 144*68017707SAndroid Build Coastguard Worker``` 145*68017707SAndroid Build Coastguard Worker</details> 146*68017707SAndroid Build Coastguard Worker 147*68017707SAndroid Build Coastguard Worker#### Maven configuration 148*68017707SAndroid Build Coastguard Worker 149*68017707SAndroid Build Coastguard WorkerMaven configuration is supported for JVM projects. 150*68017707SAndroid Build Coastguard Worker 151*68017707SAndroid Build Coastguard Worker 152*68017707SAndroid Build Coastguard Worker<details open> 153*68017707SAndroid Build Coastguard Worker<summary>Declare atomicfu version</summary> 154*68017707SAndroid Build Coastguard Worker 155*68017707SAndroid Build Coastguard Worker```xml 156*68017707SAndroid Build Coastguard Worker<properties> 157*68017707SAndroid Build Coastguard Worker <atomicfu.version>0.23.1</atomicfu.version> 158*68017707SAndroid Build Coastguard Worker</properties> 159*68017707SAndroid Build Coastguard Worker``` 160*68017707SAndroid Build Coastguard Worker 161*68017707SAndroid Build Coastguard Worker</details> 162*68017707SAndroid Build Coastguard Worker 163*68017707SAndroid Build Coastguard Worker<details> 164*68017707SAndroid Build Coastguard Worker<summary>Declare provided dependency on the AtomicFU library</summary> 165*68017707SAndroid Build Coastguard Worker 166*68017707SAndroid Build Coastguard Worker```xml 167*68017707SAndroid Build Coastguard Worker<dependencies> 168*68017707SAndroid Build Coastguard Worker <dependency> 169*68017707SAndroid Build Coastguard Worker <groupId>org.jetbrains.kotlinx</groupId> 170*68017707SAndroid Build Coastguard Worker <artifactId>atomicfu</artifactId> 171*68017707SAndroid Build Coastguard Worker <version>${atomicfu.version}</version> 172*68017707SAndroid Build Coastguard Worker <scope>provided</scope> 173*68017707SAndroid Build Coastguard Worker </dependency> 174*68017707SAndroid Build Coastguard Worker</dependencies> 175*68017707SAndroid Build Coastguard Worker``` 176*68017707SAndroid Build Coastguard Worker 177*68017707SAndroid Build Coastguard Worker</details> 178*68017707SAndroid Build Coastguard Worker 179*68017707SAndroid Build Coastguard WorkerConfigure build steps so that Kotlin compiler puts classes into a different `classes-pre-atomicfu` directory, 180*68017707SAndroid Build Coastguard Workerwhich is then transformed to a regular `classes` directory to be used later by tests and delivery. 181*68017707SAndroid Build Coastguard Worker 182*68017707SAndroid Build Coastguard Worker<details> 183*68017707SAndroid Build Coastguard Worker<summary>Build steps</summary> 184*68017707SAndroid Build Coastguard Worker 185*68017707SAndroid Build Coastguard Worker```xml 186*68017707SAndroid Build Coastguard Worker<build> 187*68017707SAndroid Build Coastguard Worker <plugins> 188*68017707SAndroid Build Coastguard Worker <!-- compile Kotlin files to staging directory --> 189*68017707SAndroid Build Coastguard Worker <plugin> 190*68017707SAndroid Build Coastguard Worker <groupId>org.jetbrains.kotlin</groupId> 191*68017707SAndroid Build Coastguard Worker <artifactId>kotlin-maven-plugin</artifactId> 192*68017707SAndroid Build Coastguard Worker <version>${kotlin.version}</version> 193*68017707SAndroid Build Coastguard Worker <executions> 194*68017707SAndroid Build Coastguard Worker <execution> 195*68017707SAndroid Build Coastguard Worker <id>compile</id> 196*68017707SAndroid Build Coastguard Worker <phase>compile</phase> 197*68017707SAndroid Build Coastguard Worker <goals> 198*68017707SAndroid Build Coastguard Worker <goal>compile</goal> 199*68017707SAndroid Build Coastguard Worker </goals> 200*68017707SAndroid Build Coastguard Worker <configuration> 201*68017707SAndroid Build Coastguard Worker <output>${project.build.directory}/classes-pre-atomicfu</output> 202*68017707SAndroid Build Coastguard Worker </configuration> 203*68017707SAndroid Build Coastguard Worker </execution> 204*68017707SAndroid Build Coastguard Worker </executions> 205*68017707SAndroid Build Coastguard Worker </plugin> 206*68017707SAndroid Build Coastguard Worker <!-- transform classes with AtomicFU plugin --> 207*68017707SAndroid Build Coastguard Worker <plugin> 208*68017707SAndroid Build Coastguard Worker <groupId>org.jetbrains.kotlinx</groupId> 209*68017707SAndroid Build Coastguard Worker <artifactId>atomicfu-maven-plugin</artifactId> 210*68017707SAndroid Build Coastguard Worker <version>${atomicfu.version}</version> 211*68017707SAndroid Build Coastguard Worker <executions> 212*68017707SAndroid Build Coastguard Worker <execution> 213*68017707SAndroid Build Coastguard Worker <goals> 214*68017707SAndroid Build Coastguard Worker <goal>transform</goal> 215*68017707SAndroid Build Coastguard Worker </goals> 216*68017707SAndroid Build Coastguard Worker <configuration> 217*68017707SAndroid Build Coastguard Worker <input>${project.build.directory}/classes-pre-atomicfu</input> 218*68017707SAndroid Build Coastguard Worker <!-- "VH" to use Java 9 VarHandle, "BOTH" to produce multi-version code --> 219*68017707SAndroid Build Coastguard Worker <variant>FU</variant> 220*68017707SAndroid Build Coastguard Worker </configuration> 221*68017707SAndroid Build Coastguard Worker </execution> 222*68017707SAndroid Build Coastguard Worker </executions> 223*68017707SAndroid Build Coastguard Worker </plugin> 224*68017707SAndroid Build Coastguard Worker </plugins> 225*68017707SAndroid Build Coastguard Worker</build> 226*68017707SAndroid Build Coastguard Worker``` 227*68017707SAndroid Build Coastguard Worker 228*68017707SAndroid Build Coastguard Worker</details> 229*68017707SAndroid Build Coastguard Worker 230*68017707SAndroid Build Coastguard Worker## Usage constraints 231*68017707SAndroid Build Coastguard Worker 232*68017707SAndroid Build Coastguard Worker* Declare atomic variables as `private val` or `internal val`. You can use just (public) `val`, 233*68017707SAndroid Build Coastguard Worker but make sure they are not directly accessed outside of your Kotlin module (outside of the source set). 234*68017707SAndroid Build Coastguard Worker Access to the atomic variable itself shall be encapsulated. 235*68017707SAndroid Build Coastguard Worker* To expose the value of an atomic property to the public, use a delegated property declared in the same scope 236*68017707SAndroid Build Coastguard Worker (see [atomic delegates](#atomic-delegates) section for details): 237*68017707SAndroid Build Coastguard Worker 238*68017707SAndroid Build Coastguard Worker```kotlin 239*68017707SAndroid Build Coastguard Workerprivate val _foo = atomic<T>(initial) // private atomic, convention is to name it with leading underscore 240*68017707SAndroid Build Coastguard Workerpublic var foo: T by _foo // public delegated property (val/var) 241*68017707SAndroid Build Coastguard Worker``` 242*68017707SAndroid Build Coastguard Worker* Only simple operations on atomic variables _directly_ are supported. 243*68017707SAndroid Build Coastguard Worker * Do not read references on atomic variables into local variables, 244*68017707SAndroid Build Coastguard Worker e.g. `top.compareAndSet(...)` is ok, while `val tmp = top; tmp...` is not. 245*68017707SAndroid Build Coastguard Worker * Do not leak references on atomic variables in other way (return, pass as params, etc). 246*68017707SAndroid Build Coastguard Worker* Do not introduce complex data flow in parameters to atomic variable operations, 247*68017707SAndroid Build Coastguard Worker i.e. `top.value = complex_expression` and `top.compareAndSet(cur, complex_expression)` are not supported 248*68017707SAndroid Build Coastguard Worker (more specifically, `complex_expression` should not have branches in its compiled representation). 249*68017707SAndroid Build Coastguard Worker Extract `complex_expression` into a variable when needed. 250*68017707SAndroid Build Coastguard Worker 251*68017707SAndroid Build Coastguard Worker## Atomicfu compiler plugin 252*68017707SAndroid Build Coastguard Worker 253*68017707SAndroid Build Coastguard WorkerTo provide a user-friendly atomic API on the frontend and efficient usage of atomic values on the backend kotlinx-atomicfu library uses the compiler plugin to transform 254*68017707SAndroid Build Coastguard WorkerIR for all the target backends: 255*68017707SAndroid Build Coastguard Worker* **JVM**: atomics are replaced with `java.util.concurrent.atomic.AtomicXxxFieldUpdater`. 256*68017707SAndroid Build Coastguard Worker* **Native**: atomics are implemented via atomic intrinsics on Kotlin/Native. 257*68017707SAndroid Build Coastguard Worker* **JS**: atomics are unboxed and represented as plain values. 258*68017707SAndroid Build Coastguard Worker 259*68017707SAndroid Build Coastguard WorkerTo turn on IR transformation set these properties in your `gradle.properties` file: 260*68017707SAndroid Build Coastguard Worker 261*68017707SAndroid Build Coastguard Worker<details open> 262*68017707SAndroid Build Coastguard Worker<summary>For Kotlin >= 1.7.20</summary> 263*68017707SAndroid Build Coastguard Worker 264*68017707SAndroid Build Coastguard Worker```groovy 265*68017707SAndroid Build Coastguard Workerkotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation 266*68017707SAndroid Build Coastguard Workerkotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformation 267*68017707SAndroid Build Coastguard Workerkotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation 268*68017707SAndroid Build Coastguard Worker``` 269*68017707SAndroid Build Coastguard Worker 270*68017707SAndroid Build Coastguard Worker</details> 271*68017707SAndroid Build Coastguard Worker 272*68017707SAndroid Build Coastguard Worker<details> 273*68017707SAndroid Build Coastguard Worker 274*68017707SAndroid Build Coastguard Worker 275*68017707SAndroid Build Coastguard Worker<summary> For Kotlin >= 1.6.20 and Kotlin < 1.7.20</summary> 276*68017707SAndroid Build Coastguard Worker 277*68017707SAndroid Build Coastguard Worker```groovy 278*68017707SAndroid Build Coastguard Workerkotlinx.atomicfu.enableIrTransformation=true // only JS IR transformation is supported 279*68017707SAndroid Build Coastguard Worker``` 280*68017707SAndroid Build Coastguard Worker 281*68017707SAndroid Build Coastguard Worker</details> 282*68017707SAndroid Build Coastguard Worker 283*68017707SAndroid Build Coastguard WorkerAlso for JS backend make sure that `ir` or `both` compiler mode is set: 284*68017707SAndroid Build Coastguard Worker 285*68017707SAndroid Build Coastguard Worker```groovy 286*68017707SAndroid Build Coastguard Workerkotlin.js.compiler=ir // or both 287*68017707SAndroid Build Coastguard Worker``` 288*68017707SAndroid Build Coastguard Worker 289*68017707SAndroid Build Coastguard Worker 290*68017707SAndroid Build Coastguard Worker## Options for post-compilation transformation 291*68017707SAndroid Build Coastguard Worker 292*68017707SAndroid Build Coastguard WorkerSome configuration options are available for _post-compilation transform tasks_ on JVM and JS. 293*68017707SAndroid Build Coastguard Worker 294*68017707SAndroid Build Coastguard WorkerTo set configuration options you should create `atomicfu` section in a `build.gradle` file, 295*68017707SAndroid Build Coastguard Workerlike this: 296*68017707SAndroid Build Coastguard Worker```groovy 297*68017707SAndroid Build Coastguard Workeratomicfu { 298*68017707SAndroid Build Coastguard Worker dependenciesVersion = '0.23.1' 299*68017707SAndroid Build Coastguard Worker} 300*68017707SAndroid Build Coastguard Worker``` 301*68017707SAndroid Build Coastguard Worker 302*68017707SAndroid Build Coastguard Worker### JVM options 303*68017707SAndroid Build Coastguard Worker 304*68017707SAndroid Build Coastguard WorkerTo turn off transformation for Kotlin/JVM set option `transformJvm` to `false`. 305*68017707SAndroid Build Coastguard Worker 306*68017707SAndroid Build Coastguard WorkerConfiguration option `jvmVariant` defines the Java class that replaces atomics during bytecode transformation. 307*68017707SAndroid Build Coastguard WorkerHere are the valid options: 308*68017707SAndroid Build Coastguard Worker- `FU` – atomics are replaced with [AtomicXxxFieldUpdater](https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.html). 309*68017707SAndroid Build Coastguard Worker- `VH` – atomics are replaced with [VarHandle](https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html), 310*68017707SAndroid Build Coastguard Worker this option is supported for JDK 9+. 311*68017707SAndroid Build Coastguard Worker- `BOTH` – [multi-release jar file](https://openjdk.java.net/jeps/238) will be created with both `AtomicXxxFieldUpdater` for JDK <= 8 and `VarHandle` for JDK 9+. 312*68017707SAndroid Build Coastguard Worker 313*68017707SAndroid Build Coastguard Worker### JS options 314*68017707SAndroid Build Coastguard Worker 315*68017707SAndroid Build Coastguard WorkerTo turn off transformation for Kotlin/JS set option `transformJs` to `false`. 316*68017707SAndroid Build Coastguard Worker 317*68017707SAndroid Build Coastguard WorkerHere are all available configuration options (with their defaults): 318*68017707SAndroid Build Coastguard Worker```groovy 319*68017707SAndroid Build Coastguard Workeratomicfu { 320*68017707SAndroid Build Coastguard Worker dependenciesVersion = '0.23.1' // set to null to turn-off auto dependencies 321*68017707SAndroid Build Coastguard Worker transformJvm = true // set to false to turn off JVM transformation 322*68017707SAndroid Build Coastguard Worker jvmVariant = "FU" // JVM transformation variant: FU,VH, or BOTH 323*68017707SAndroid Build Coastguard Worker transformJs = true // set to false to turn off JVM transformation 324*68017707SAndroid Build Coastguard Worker} 325*68017707SAndroid Build Coastguard Worker``` 326*68017707SAndroid Build Coastguard Worker 327*68017707SAndroid Build Coastguard Worker## More features 328*68017707SAndroid Build Coastguard Worker 329*68017707SAndroid Build Coastguard WorkerAtomicFU provides some additional features that you can use. 330*68017707SAndroid Build Coastguard Worker 331*68017707SAndroid Build Coastguard Worker### Arrays of atomic values 332*68017707SAndroid Build Coastguard Worker 333*68017707SAndroid Build Coastguard WorkerYou can declare arrays of all supported atomic value types. 334*68017707SAndroid Build Coastguard WorkerBy default arrays are transformed into the corresponding `java.util.concurrent.atomic.Atomic*Array` instances. 335*68017707SAndroid Build Coastguard Worker 336*68017707SAndroid Build Coastguard WorkerIf you configure `variant = "VH"` an array will be transformed to plain array using 337*68017707SAndroid Build Coastguard Worker[VarHandle](https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html) to support atomic operations. 338*68017707SAndroid Build Coastguard Worker 339*68017707SAndroid Build Coastguard Worker```kotlin 340*68017707SAndroid Build Coastguard Workerval a = atomicArrayOfNulls<T>(size) // similar to Array constructor 341*68017707SAndroid Build Coastguard Worker 342*68017707SAndroid Build Coastguard Workerval x = a[i].value // read value 343*68017707SAndroid Build Coastguard Workera[i].value = x // set value 344*68017707SAndroid Build Coastguard Workera[i].compareAndSet(expect, update) // do atomic operations 345*68017707SAndroid Build Coastguard Worker``` 346*68017707SAndroid Build Coastguard Worker 347*68017707SAndroid Build Coastguard Worker### Atomic delegates 348*68017707SAndroid Build Coastguard Worker 349*68017707SAndroid Build Coastguard WorkerYou can expose the value of an atomic property to the public, using a delegated property 350*68017707SAndroid Build Coastguard Workerdeclared in the same scope: 351*68017707SAndroid Build Coastguard Worker 352*68017707SAndroid Build Coastguard Worker```kotlin 353*68017707SAndroid Build Coastguard Workerprivate val _foo = atomic<T>(initial) // private atomic, convention is to name it with leading underscore 354*68017707SAndroid Build Coastguard Workerpublic var foo: T by _foo // public delegated property (val/var) 355*68017707SAndroid Build Coastguard Worker``` 356*68017707SAndroid Build Coastguard Worker 357*68017707SAndroid Build Coastguard WorkerYou can also delegate a property to the atomic factory invocation, that is equal to declaring a volatile property: 358*68017707SAndroid Build Coastguard Worker 359*68017707SAndroid Build Coastguard Worker```kotlin 360*68017707SAndroid Build Coastguard Workerpublic var foo: T by atomic(0) 361*68017707SAndroid Build Coastguard Worker``` 362*68017707SAndroid Build Coastguard Worker 363*68017707SAndroid Build Coastguard WorkerThis feature is only supported for the IR transformation mode, see the [atomicfu compiler plugin](#atomicfu-compiler-plugin) section for details. 364*68017707SAndroid Build Coastguard Worker 365*68017707SAndroid Build Coastguard Worker### User-defined extensions on atomics 366*68017707SAndroid Build Coastguard Worker 367*68017707SAndroid Build Coastguard WorkerYou can define you own extension functions on `AtomicXxx` types but they must be `inline` and they cannot 368*68017707SAndroid Build Coastguard Workerbe public and be used outside of the module they are defined in. For example: 369*68017707SAndroid Build Coastguard Worker 370*68017707SAndroid Build Coastguard Worker```kotlin 371*68017707SAndroid Build Coastguard Worker@Suppress("NOTHING_TO_INLINE") 372*68017707SAndroid Build Coastguard Workerprivate inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true) 373*68017707SAndroid Build Coastguard Worker``` 374*68017707SAndroid Build Coastguard Worker 375*68017707SAndroid Build Coastguard Worker### Locks 376*68017707SAndroid Build Coastguard Worker 377*68017707SAndroid Build Coastguard WorkerThis project includes `kotlinx.atomicfu.locks` package providing multiplatform locking primitives that 378*68017707SAndroid Build Coastguard Workerrequire no additional runtime dependencies on Kotlin/JVM and Kotlin/JS with a library implementation for 379*68017707SAndroid Build Coastguard WorkerKotlin/Native. 380*68017707SAndroid Build Coastguard Worker 381*68017707SAndroid Build Coastguard Worker* `SynchronizedObject` is designed for inheritance. You write `class MyClass : SynchronizedObject()` and then 382*68017707SAndroid Build Coastguard Workeruse `synchronized(instance) { ... }` extension function similarly to the 383*68017707SAndroid Build Coastguard Worker[synchronized](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/synchronized.html) 384*68017707SAndroid Build Coastguard Workerfunction from the standard library that is available for JVM. The `SynchronizedObject` superclass gets erased 385*68017707SAndroid Build Coastguard Worker(transformed to `Any`) on JVM and JS, with `synchronized` leaving no trace in the code on JS and getting 386*68017707SAndroid Build Coastguard Workerreplaced with built-in monitors for locking on JVM. 387*68017707SAndroid Build Coastguard Worker 388*68017707SAndroid Build Coastguard Worker* `ReentrantLock` is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and 389*68017707SAndroid Build Coastguard Workeruse `lock`/`tryLock`/`unlock` functions or `lock.withLock { ... }` extension function similarly to the way 390*68017707SAndroid Build Coastguard Worker[jucl.ReentrantLock](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html) 391*68017707SAndroid Build Coastguard Workeris used on JVM. On JVM it is a typealias to the later class, erased on JS. 392*68017707SAndroid Build Coastguard Worker 393*68017707SAndroid Build Coastguard Worker> Note that package `kotlinx.atomicfu.locks` is experimental explicitly even while atomicfu is experimental itself, 394*68017707SAndroid Build Coastguard Worker> meaning that no ABI guarantees are provided whatsoever. API from this package is not recommended to use in libraries 395*68017707SAndroid Build Coastguard Worker> that other projects depend on. 396*68017707SAndroid Build Coastguard Worker 397*68017707SAndroid Build Coastguard Worker### Tracing operations 398*68017707SAndroid Build Coastguard Worker 399*68017707SAndroid Build Coastguard WorkerYou can debug your tests tracing atomic operations with a special trace object: 400*68017707SAndroid Build Coastguard Worker 401*68017707SAndroid Build Coastguard Worker```kotlin 402*68017707SAndroid Build Coastguard Workerprivate val trace = Trace() 403*68017707SAndroid Build Coastguard Workerprivate val current = atomic(0, trace) 404*68017707SAndroid Build Coastguard Worker 405*68017707SAndroid Build Coastguard Workerfun update(x: Int): Int { 406*68017707SAndroid Build Coastguard Worker // custom trace message 407*68017707SAndroid Build Coastguard Worker trace { "calling update($x)" } 408*68017707SAndroid Build Coastguard Worker // automatic tracing of modification operations 409*68017707SAndroid Build Coastguard Worker return current.getAndAdd(x) 410*68017707SAndroid Build Coastguard Worker} 411*68017707SAndroid Build Coastguard Worker``` 412*68017707SAndroid Build Coastguard Worker 413*68017707SAndroid Build Coastguard WorkerAll trace messages are stored in a cyclic array inside `trace`. 414*68017707SAndroid Build Coastguard Worker 415*68017707SAndroid Build Coastguard WorkerYou can optionally set the size of trace's message array and format function. For example, 416*68017707SAndroid Build Coastguard Workeryou can add a current thread name to the traced messages: 417*68017707SAndroid Build Coastguard Worker 418*68017707SAndroid Build Coastguard Worker```kotlin 419*68017707SAndroid Build Coastguard Workerprivate val trace = Trace(size = 64) { 420*68017707SAndroid Build Coastguard Worker index, // index of a trace message 421*68017707SAndroid Build Coastguard Worker text // text passed when invoking trace { text } 422*68017707SAndroid Build Coastguard Worker -> "$index: [${Thread.currentThread().name}] $text" 423*68017707SAndroid Build Coastguard Worker} 424*68017707SAndroid Build Coastguard Worker``` 425*68017707SAndroid Build Coastguard Worker 426*68017707SAndroid Build Coastguard Worker`trace` is only seen before transformation and completely erased after on Kotlin/JVM and Kotlin/JS. 427*68017707SAndroid Build Coastguard Worker 428*68017707SAndroid Build Coastguard Worker## Kotlin Native support 429*68017707SAndroid Build Coastguard Worker 430*68017707SAndroid Build Coastguard WorkerAtomic references for Kotlin/Native are based on 431*68017707SAndroid Build Coastguard Worker[FreezableAtomicReference](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-freezable-atomic-reference/-init-.html) 432*68017707SAndroid Build Coastguard Workerand every reference that is stored to the previously 433*68017707SAndroid Build Coastguard Worker[frozen](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/freeze.html) 434*68017707SAndroid Build Coastguard Worker(shared with another thread) atomic is automatically frozen, too. 435*68017707SAndroid Build Coastguard Worker 436*68017707SAndroid Build Coastguard WorkerSince Kotlin/Native does not generally provide binary compatibility between versions, 437*68017707SAndroid Build Coastguard Workeryou should use the same version of Kotlin compiler as was used to build AtomicFU. 438*68017707SAndroid Build Coastguard WorkerSee [gradle.properties](gradle.properties) in AtomicFU project for its `kotlin_version`. 439*68017707SAndroid Build Coastguard Worker 440*68017707SAndroid Build Coastguard WorkerAvailable Kotlin/Native targets are based on non-deprecated official targets [Tier list](https://kotlinlang.org/docs/native-target-support.html) 441*68017707SAndroid Build Coastguard Worker with the corresponding compatibility guarantees. 442