xref: /aosp_15_r20/external/kotlinx.atomicfu/README.md (revision 68017707106cb9da9fed635c150bc497c09c160f)
1*68017707SAndroid Build Coastguard Worker# AtomicFU
2*68017707SAndroid Build Coastguard Worker
3*68017707SAndroid Build Coastguard Worker[![Kotlin Beta](https://kotl.in/badges/beta.svg)](https://kotlinlang.org/docs/components-stability.html)
4*68017707SAndroid Build Coastguard Worker[![JetBrains official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
5*68017707SAndroid Build Coastguard Worker[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)
6*68017707SAndroid Build Coastguard Worker[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/atomicfu)](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