From c1a5a280f5352bf607b3d735e9d7b4604ed0aa17 Mon Sep 17 00:00:00 2001
From: mvicsokolova <82594708+mvicsokolova@users.noreply.github.com>
Date: Tue, 25 Oct 2022 12:55:08 +0200
Subject: Readme update (#256)
* README update
* minor fixes
---
README.md | 351 ++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 207 insertions(+), 144 deletions(-)
diff --git a/README.md b/README.md
index c34cd44..251bb0e 100644
--- a/README.md
+++ b/README.md
@@ -9,26 +9,41 @@
>We do provide a compatibility of atomicfu-transformed artifacts between releases, but we do not provide
>strict compatibility guarantees on plugin API and its general stability between Kotlin versions.
-The idiomatic way to use atomic operations in Kotlin.
-
-* 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.
-* Use Kotlin-specific extensions (e.g. inline `updateAndGet` and `getAndUpdate` functions).
-* Compile-time dependency only for JVM and JS/IR (no runtime dependencies).
- * Post-compilation bytecode transformer that declares all the relevant field updaters for you on [Kotlin/JVM](#jvm).
- * Post-compilation JavaScript files transformer on [Kotlin/JS](#js).
-* Multiplatform:
- * [Kotlin/Native](#native) is supported.
- * However, Kotlin/Native works as library dependency at the moment (unlike Kotlin/JVM and Kotlin/JS).
- * This enables writing [common](#common) Kotlin code with atomics that compiles for JVM, JS, and Native.
-* [Gradle](#gradle-build-setup) for all platforms and [Maven](#maven-build-setup) for JVM are supported.
-* [Additional features](#additional-features) include:
- * [JDK9 VarHandle](#varhandles-with-java-9).
- * [Arrays of atomic values](#arrays-of-atomic-values).
- * [User-defined extensions on atomics](#user-defined-extensions-on-atomics)
- * [Locks](#locks)
- * [Tracing operations](#tracing-operations)
-
+**Atomicfu** is a multiplatform library that provides the idiomatic and effective way of using atomic operations in Kotlin.
+
+## Table of contents
+- [Features](#features)
+- [Example](#example)
+- [Quickstart](#quickstart)
+ - [Apply plugin to a project](#apply-plugin)
+ - [Gradle configuration](#gradle-configuration)
+ - [Maven configuration](#maven-configuration)
+- [Usage constraints](#usage-constraints)
+- [Transformation modes](#transformation-modes)
+ - [Atomicfu compiler plugin](#atomicfu-compiler-plugin)
+- [Options for post-compilation transformation](#options-for-post-compilation-transformation)
+ - [JVM options](#jvm-options)
+ - [JS options](#js-options)
+- [More features](#more-features)
+ - [Arrays of atomic values](#arrays-of-atomic-values)
+ - [User-defined extensions on atomics](#user-defined-extensions-on-atomics)
+ - [Locks](#locks)
+ - [Tracing operations](#tracing-operations)
+- [Kotlin/Native support](#kotlin-native-support)
+
+
+## Features
+
+* Code it like a boxed value `atomic(0)`, but run it in production efficiently:
+ * as `java.util.concurrent.atomic.AtomicXxxFieldUpdater` on Kotlin/JVM
+ * as a plain unboxed value on Kotlin/JS
+* Multiplatform: write common Kotlin code with atomics that compiles for Kotlin JVM, JS, and Native backends:
+ * Compile-only dependency for JVM and JS (no runtime dependencies)
+ * Compile and runtime dependency for Kotlin/Native
+* Use Kotlin-specific extensions (e.g. inline `loop`, `update`, `updateAndGet` functions).
+* Use atomic arrays, user-defined extensions on atomics and locks (see [more features](#more-features)).
+* [Tracing operations](#tracing-operations) for debugging.
+
## Example
Let us declare a `top` variable for a lock-free stack implementation:
@@ -78,14 +93,140 @@ val myLong = atomic(0L) // note: long initial value
Integer and long atomics provide all the usual `getAndIncrement`, `incrementAndGet`, `getAndAdd`, `addAndGet`, and etc
operations. They can be also atomically modified via `+=` and `-=` operators.
-## Dos and Don'ts
+## Quickstart
+### Apply plugin
+#### Gradle configuration
+
+Gradle configuration is supported for all platforms, minimal version is Gradle 6.8.
+
+In top-level build file:
+
+
+Kotlin
+
+```kotlin
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.18.4")
+ }
+}
+
+apply(plugin = "kotlinx-atomicfu")
+```
+
+
+
+Groovy
+
+```groovy
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.18.4'
+ }
+}
+
+apply plugin: 'kotlinx-atomicfu'
+```
+
+
+#### Maven configuration
+
+Maven configuration is supported for JVM projects.
+
+
+
+Declare atomicfu version
+
+```xml
+
+ 0.18.4
+
+```
+
+
+
+
+Declare provided dependency on the AtomicFU library
+
+```xml
+
+
+ org.jetbrains.kotlinx
+ atomicfu
+ ${atomicfu.version}
+ provided
+
+
+```
+
+
+
+Configure build steps so that Kotlin compiler puts classes into a different `classes-pre-atomicfu` directory,
+which is then transformed to a regular `classes` directory to be used later by tests and delivery.
+
+
+Build steps
+
+```xml
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+
+
+
+
+
+
+ org.jetbrains.kotlinx
+ atomicfu-maven-plugin
+ ${atomicfu.version}
+
+
+
+ transform
+
+
+ ${project.build.directory}/classes-pre-atomicfu
+
+ FU
+
+
+
+
+
+
+```
+
+
+
+## Usage constraints
* Declare atomic variables as `private val` or `internal val`. You can use just (public) `val`,
but make sure they are not directly accessed outside of your Kotlin module (outside of the source set).
Access to the atomic variable itself shall be encapsulated.
* Only simple operations on atomic variables _directly_ are supported.
* Do not read references on atomic variables into local variables,
- e.g. `top.compareAndSet(...)` is Ok, while `val tmp = top; tmp...` is not.
+ e.g. `top.compareAndSet(...)` is ok, while `val tmp = top; tmp...` is not.
* Do not leak references on atomic variables in other way (return, pass as params, etc).
* Do not introduce complex data flow in parameters to atomic variable operations,
i.e. `top.value = complex_expression` and `top.compareAndSet(cur, complex_expression)` are not supported
@@ -96,72 +237,53 @@ operations. They can be also atomically modified via `+=` and `-=` operators.
```kotlin
private val _foo = atomic(initial) // private atomic, convention is to name it with leading underscore
public var foo: T by _foo // public delegated property (val/var)
-```
+```
-## Gradle build setup
+## Transformation modes
-Building with Gradle is supported for all platforms.
+Basically, Atomicfu library provides an effective usage of atomic values by performing the transformations of the compiled code.
+For JVM and JS there 2 transformation modes available:
+* **Post-compilation transformation** that modifies the compiled bytecode or `*.js` files.
+* **IR transformation** that is performed by the atomicfu compiler plugin.
-### JVM
+### Atomicfu compiler plugin
-You will need Gradle 6.8 or later.
-Add and apply AtomicFU plugin. It adds all the corresponding dependencies and transformations automatically.
-See [additional configuration](#additional-configuration) if that needs tweaking.
+Compiler plugin transformation is less fragile than transformation of the compiled sources
+as it depends on the compiler IR tree.
-```groovy
-buildscript {
- ext.atomicfu_version = '0.18.4'
+To turn on IR transformation set these properties in your `gradle.properties` file:
- dependencies {
- classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicfu_version"
- }
-}
+
+For Kotlin >= 1.7.20
-apply plugin: 'kotlinx-atomicfu'
+```groovy
+kotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation
+kotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation
```
-### JS
-
-Configure add apply plugin just like for [JVM](#jvm).
+
-### Native
+
-This library is available for Kotlin/Native (`atomicfu-native`).
-Apply the corresponding plugin just like for [JVM](#jvm).
-Atomic references for Kotlin/Native are based on
-[FreezableAtomicReference](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-freezable-atomic-reference/-init-.html)
-and every reference that is stored to the previously
-[frozen](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/freeze.html)
-(shared with another thread) atomic is automatically frozen, too.
+ For Kotlin >= 1.6.20 and Kotlin < 1.7.20
-Since Kotlin/Native does not generally provide binary compatibility between versions,
-you should use the same version of Kotlin compiler as was used to build AtomicFU.
-See [gradle.properties](gradle.properties) in AtomicFU project for its `kotlin_version`.
+```groovy
+kotlinx.atomicfu.enableIrTransformation=true // only JS IR transformation is supported
+```
-### Common
+
-If you write a common code that should get compiled or different platforms, add `org.jetbrains.kotlinx:atomicfu`
-to your common code dependencies or apply `kotlinx-atomicfu` plugin that adds this dependency automatically:
+Also for JS backend make sure that `ir` or `both` compiler mode is set:
```groovy
-dependencies {
- compile "org.jetbrains.kotlinx:atomicfu:$atomicfu_version"
-}
+kotlin.js.compiler=ir // or both
```
-## IR transformation for Kotlin/JS
-
-There is a new option to turn on IR transformation for Kotlin/JS backend.
-You can add `kotlinx.atomicfu.enableIrTransformation=true` to your `gradle.properties` file in order to enable it.
-Here is how transformation is performed for different [JS compiler modes](https://kotlinlang.org/docs/js-ir-compiler.html) with this option enabled:
+## Options for post-compilation transformation
-- `kotlin.js.compiler=legacy`: JavaScript transformer from the library is applied to the final compiled *.js files.
-- `kotlin.js.compiler=ir`: compiler plugin transformations are appiled to the generated IR.
-- `kotlin.js.compiler=both`: compiler plugin transformations are appiled to all compilations of IR targets, while compilations of legacy targets are transformed by the library.
-
-## Additional configuration
+Some configuration options are available for _post-compilation transform tasks_ on JVM and JS.
To set configuration options you should create `atomicfu` section in a `build.gradle` file,
like this:
@@ -171,7 +293,7 @@ atomicfu {
}
```
-### JVM transformation options
+### JVM options
To turn off transformation for Kotlin/JVM set option `transformJvm` to `false`.
@@ -182,7 +304,7 @@ Here are the valid options:
this option is supported for JDK 9+.
- `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+.
-### JS transformation options
+### JS options
To turn off transformation for Kotlin/JS set option `transformJs` to `false`.
@@ -191,85 +313,14 @@ Here are all available configuration options (with their defaults):
atomicfu {
dependenciesVersion = '0.18.4' // set to null to turn-off auto dependencies
transformJvm = true // set to false to turn off JVM transformation
- jvmVariant = "FU" // JVM transformation variant: FU,VH, or BOTH
- jsVariant = "JS" // JS transformation variant: JS or IR
- verbose = false // set to true to be more verbose
+ jvmVariant = "FU" // JVM transformation variant: FU,VH, or BOTH
+ transformJs = true // set to false to turn off JVM transformation
}
```
-## Maven build setup
-
-Declare AtomicFU version:
-
-```xml
-
- 0.18.4
-
-```
-
-Declare _provided_ dependency on the AtomicFU library
-(the users of the resulting artifact will not have a dependency on AtomicFU library):
-
-```xml
-
-
- org.jetbrains.kotlinx
- atomicfu
- ${atomicfu.version}
- provided
-
-
-```
-
-Configure build steps so that Kotlin compiler puts classes into a different `classes-pre-atomicfu` directory,
-which is then transformed to a regular `classes` directory to be used later by tests and delivery.
-
-```xml
-
-
-
-
- org.jetbrains.kotlin
- kotlin-maven-plugin
- ${kotlin.version}
-
-
- compile
- compile
-
- compile
-
-
-
-
-
-
-
-
-
- org.jetbrains.kotlinx
- atomicfu-maven-plugin
- ${atomicfu.version}
-
-
-
- transform
-
-
- ${project.build.directory}/classes-pre-atomicfu
-
- FU
-
-
-
-
-
-
-```
+## More features
-## Additional features
-
-AtomicFU provides some additional features that you can optionally use.
+AtomicFU provides some additional features that you can use.
### Arrays of atomic values
@@ -350,3 +401,15 @@ private val trace = Trace(size = 64) {
`trace` is only seen before transformation and completely erased after on Kotlin/JVM and Kotlin/JS.
+## Kotlin Native support
+
+Atomic references for Kotlin/Native are based on
+[FreezableAtomicReference](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-freezable-atomic-reference/-init-.html)
+and every reference that is stored to the previously
+[frozen](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/freeze.html)
+(shared with another thread) atomic is automatically frozen, too.
+
+Since Kotlin/Native does not generally provide binary compatibility between versions,
+you should use the same version of Kotlin compiler as was used to build AtomicFU.
+See [gradle.properties](gradle.properties) in AtomicFU project for its `kotlin_version`.
+
--
cgit v1.2.3