### Checkout Develop Branch Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/RELEASE.md Start by checking out the 'develop' branch of the repository. ```bash git checkout develop ``` -------------------------------- ### Basic Tracing Example Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Demonstrates basic atomic tracing by initializing a `Trace` instance and associating it with an atomic variable. Operations on the atomic are automatically logged. ```kotlin import kotlinx.atomicfu.* private val trace = Trace(size = 32) private val value = atomic(0, trace) fun update(newValue: Int) { value.value = newValue // Automatically traced as "set($newValue)" } fun compareAndSwap(expected: Int, updated: Int): Boolean { trace { "Attempting CAS($expected, $updated)" } return value.compareAndSet(expected, updated) } // Later, print trace println(trace) ``` -------------------------------- ### Complete AtomicFU Gradle Configuration Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Example of a complete AtomicFU configuration block in a Gradle build script, including plugin application and various settings. ```gradle plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } atomicfu { dependenciesVersion = "0.33.0" transformJvm = true jvmVariant = "FU" } ``` -------------------------------- ### Example Usage of updateAndGet for Ensuring Readiness Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-boolean.md Demonstrates how to use updateAndGet to atomically update a flag and perform an action if the flag was initially false. This ensures that preparation logic runs only once. ```kotlin private val ready = atomic(false) fun ensureReady(): Boolean { return ready.updateAndGet { if (!it) startPrep(); true else it } } ``` -------------------------------- ### Minimize Contention Example Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Demonstrates how to reduce contention by distributing atomic operations across threads instead of using a single shared atomic variable. ```kotlin // ❌ High contention private val shared = atomic(0) fun increment() { shared.update { it + 1 } } // ✓ Better - distribute across threads private val counters = Array(16) { atomic(0) } fun increment(threadId: Int) { counters[threadId].update { it + 1 } } ``` -------------------------------- ### Gradle Plugin Application (Groovy) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Apply the Kotlinx AtomicFU Gradle plugin using Groovy syntax in your top-level build file. This example uses version 0.33.0. ```groovy plugins { id 'org.jetbrains.kotlinx.atomicfu' version '0.33.0' } ``` -------------------------------- ### Custom Trace Format with Context Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Shows how to configure a `Trace` with a custom `TraceFormat` lambda. This example includes timestamp and thread name in the formatted trace output for enhanced debugging context. ```kotlin private val trace = Trace( size = 128, format = TraceFormat { index, event -> val thread = Thread.currentThread().name val timestamp = System.currentTimeMillis() % 100000 "[$timestamp ms] [$thread] #$index: $event" } ) ``` -------------------------------- ### Race Condition Example in State Machine Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Illustrates a common race condition when checking state before acting. Use compareAndSet for atomic state updates instead. ```kotlin // ✗ Bad: time-of-check to time-of-use race if (state.value == State.RUNNING) { start() // Another thread might have changed state } // ✓ Good: use compareAndSet val success = state.compareAndSet(State.IDLE, State.RUNNING) ``` -------------------------------- ### Avoid Lock Contention Example Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Illustrates reducing lock contention by minimizing the time spent within a critical section. Lock only the essential part of the operation. ```kotlin // ❌ Long critical section lock.withLock { val data = slowNetworkCall() updateSharedState(data) } // ✓ Better - lock only for critical part val data = slowNetworkCall() lock.withLock { updateSharedState(data) } ``` -------------------------------- ### AtomicFU loop() Extension Function Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Provides an example of the loop() extension function, which repeatedly reads an atomic value, useful for spin-loops. It includes a check for null before processing. ```kotlin head.loop { current -> if (current == null) return@loop // Process current } ``` -------------------------------- ### Protected Resource using SynchronizedObject Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Example of protecting a resource using Kotlin's SynchronizedObject and the synchronized block for thread safety. ```kotlin class Resource : SynchronizedObject() { private var value = 0 fun increment() { synchronized(this) { value++ } } } ``` -------------------------------- ### getValue() / setValue() Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Property delegate operators for AtomicInt allowing direct property access to get and set the atomic value. ```APIDOC ## getValue() / setValue() ### Description Property delegate operators for AtomicInt allowing direct property access to get and set the atomic value. ### Method Signature ```kotlin @InlineOnly public inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Int @InlineOnly public inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) ``` ### Return Type `getValue`: `Int` `setValue`: `Unit` ``` -------------------------------- ### Get and Add to AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `getAndAdd` to atomically add a delta to the value of an AtomicInt and return the value before the addition. ```kotlin public fun getAndAdd(delta: Int): Int ``` ```kotlin private val totalProcessed = atomic(0) fun addProcessedCount(count: Int): Int { return totalProcessed.getAndAdd(count) } ``` -------------------------------- ### Decrement and Get AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `decrementAndGet` to atomically decrement the value of an AtomicInt by 1 and return the value after the decrement. ```kotlin public fun decrementAndGet(): Int ``` -------------------------------- ### Get and Increment AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `getAndIncrement` to atomically increment the value of an AtomicInt by 1 and return the value before the increment. ```kotlin public fun getAndIncrement(): Int ``` ```kotlin private val requestId = atomic(0) fun getNextRequestId(): Int { return requestId.getAndIncrement() } ``` -------------------------------- ### Increment and Get AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `incrementAndGet` to atomically increment the value of an AtomicInt by 1 and return the value after the increment. ```kotlin public fun incrementAndGet(): Int ``` ```kotlin private val taskCounter = atomic(0) fun incrementTaskCount(): Int { return taskCounter.incrementAndGet() } ``` -------------------------------- ### Cache Implementation with ReentrantLock Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-locks.md Demonstrates a thread-safe cache using ReentrantLock for get, put, and getOrCompute operations. Ensures that map access is synchronized. ```kotlin import kotlinx.atomicfu.locks.* class Cache { private val lock = reentrantLock() private val data = mutableMapOf fun get(key: K): V? = lock.withLock { data[key] } fun put(key: K, value: V) { lock.withLock { data[key] = value } } fun getOrCompute(key: K, compute: () -> V): V = lock.withLock { data.getOrPut(key) { compute() } } } ``` -------------------------------- ### Get and Decrement AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `getAndDecrement` to atomically decrement the value of an AtomicInt by 1 and return the value before the decrement. ```kotlin public fun getAndDecrement(): Int ``` -------------------------------- ### Atomic Operation with SynchronousMutex Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-locks.md Example of performing an atomic operation using SynchronousMutex. The withLock block guarantees that the operation is executed exclusively by one thread at a time. ```kotlin import kotlinx.atomicfu.locks.* import kotlin.time.Duration.Companion.milliseconds val mutex = SynchronousMutex() fun atomicOperation(): String = mutex.withLock { // Only one thread at a time "result" } ``` -------------------------------- ### Get and Set AtomicInt Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Use `getAndSet` to atomically set the value of an AtomicInt to a new value and return the old value. ```kotlin public fun getAndSet(value: Int): Int ``` ```kotlin private val state = atomic(0) fun resetAndGetOld(newState: Int): Int { return state.getAndSet(newState) } ``` -------------------------------- ### Reentrant Lock Example Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-locks.md Demonstrates the reentrant nature of ReentrantLock, where the same thread can acquire the lock multiple times. Ensure each lock() call has a corresponding unlock() call. ```kotlin val lock = reentrantLock() fun reentrantExample() { lock.lock() try { // First level lock.lock() // Same thread can acquire again try { // Both locks held } finally { lock.unlock() } // Still holding first lock } finally { lock.unlock() // Release first lock } } ``` -------------------------------- ### Decrement and Get AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically decrements the value by 1 and returns the new value. ```kotlin public fun decrementAndGet(): Long ``` -------------------------------- ### Get and Decrement AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically decrements the value by 1 and returns the old value. ```kotlin public fun getAndDecrement(): Long ``` -------------------------------- ### Atomically Add and Get Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Atomically adds a delta to the current value and returns the new value. Use when you need to update an atomic integer and immediately use its new value. ```kotlin private val score = atomic(0) fun incrementScore(points: Int): Int { return score.addAndGet(points) } ``` -------------------------------- ### Increment and Get AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically increments the value by 1 and returns the new value. ```kotlin public fun incrementAndGet(): Long ``` -------------------------------- ### Typical Kotlin/Multiplatform Project Structure Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Illustrates a standard project structure for Kotlin Multiplatform projects using AtomicFU, showing the placement of common and platform-specific source sets. ```plaintext src/ ├── commonMain/kotlin/ │ └── kotlinx/atomicfu/ │ ├── AtomicFU.common.kt (expect declarations) │ ├── Trace.common.kt │ └── locks/Synchronized.common.kt jvmMain/kotlin/ │ └── kotlinx/atomicfu/ │ ├── AtomicFU.kt (actual JVM implementation) │ └── Trace.kt jsMain/kotlin/ │ └── (minimal; mostly erased) nativeMain/kotlin/ │ └── (native-specific implementations) ``` -------------------------------- ### Get and Update Atomic Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-int.md Atomically updates the value using a function and returns the *old* value before the update. Useful when you need to know the state of the atomic variable prior to modification. ```kotlin private val generation = atomic(0) fun nextGeneration(): Int { return generation.updateAndGet { it + 1 } } ``` -------------------------------- ### Maven Configuration: Build Steps Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Configure Maven build steps to compile Kotlin files to a staging directory and then transform them using the AtomicFU plugin. This ensures proper handling of atomic variables. ```xml org.jetbrains.kotlin kotlin-maven-plugin ${kotlin.version} compile compile compile ${project.build.directory}/classes-pre-atomicfu org.jetbrains.kotlinx atomicfu-maven-plugin ${atomicfu.version} transform ${project.build.directory}/classes-pre-atomicfu FU ``` -------------------------------- ### Get and Increment AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically increments the value by 1 and returns the old value. ```kotlin public fun getAndIncrement(): Long ``` ```kotlin private val eventId = atomic(0L) fun getNextEventId(): Long { return eventId.getAndIncrement() } ``` -------------------------------- ### Get and Set AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically sets the given value and returns the old value. ```kotlin public fun getAndSet(value: Long): Long ``` ```kotlin private val sequenceNumber = atomic(0L) fun getAndSetSequence(newNumber: Long): Long { return sequenceNumber.getAndSet(newNumber) } ``` -------------------------------- ### Add and Get AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically adds the given delta to the value and returns the new value. ```kotlin public fun addAndGet(delta: Long): Long ``` ```kotlin private val memoryUsed = atomic(0L) fun allocateMemory(bytes: Long): Long { return memoryUsed.addAndGet(bytes) } ``` -------------------------------- ### AtomicFU Module Structure Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Illustrates the directory structure of the AtomicFU project, showing the core library, plugins, transformer, and testing modules. ```text kotlinx-atomicfu/ ├── atomicfu/ # Core library │ ├── src/commonMain/ # Common API (expect declarations) │ ├── src/jvmMain/ # JVM implementations │ ├── src/jsMain/ # JS support │ └── src/nativeMain/ # Kotlin/Native implementations ├── atomicfu-gradle-plugin/ # Gradle plugin for configuration ├── atomicfu-maven-plugin/ # Maven plugin support ├── atomicfu-transformer/ # Bytecode transformer (legacy) └── integration-testing/ # Examples and tests ``` -------------------------------- ### Enable Trace Output for Debugging Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Demonstrates how to enable trace output for debugging atomic operations. Pass a `Trace` instance during atomic creation and call it manually or inspect it later. ```kotlin val trace = Trace(size = 64) private val value = atomic(0, trace) // Call trace manually trace { "Important event" } // Later, inspect trace println(trace) ``` -------------------------------- ### Get and Add AtomicLong Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Atomically adds the given delta to the value and returns the old value. ```kotlin public fun getAndAdd(delta: Long): Long ``` ```kotlin private val totalBytes = atomic(0L) fun addTransferredBytes(bytes: Long): Long { return totalBytes.getAndAdd(bytes) } ``` -------------------------------- ### AtomicLong Property Delegates Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-long.md Defines property delegate operators for getting and setting atomic long values. ```kotlin @InlineOnly public inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Long ``` ```kotlin @InlineOnly public inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Long) ``` -------------------------------- ### View Transformed Bytecode with Gradle Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Build your project with Gradle and then use `javap` to inspect the transformed bytecode. Transformed classes are typically found in `build/classes/kotlin/main/`. ```bash ./gradlew build # Look in: build/classes/kotlin/main/ javap -c MyClass.class ``` -------------------------------- ### View Transformed Bytecode with Maven Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Compile your project with Maven and then use `javap` to inspect the transformed bytecode. Check `target/classes-pre-atomicfu/` for pre-transformation and `target/classes/` for post-transformation. ```bash mvn clean compile # Look in: target/classes-pre-atomicfu/ (before) and target/classes/ (after) javap -c MyClass.class ``` -------------------------------- ### Configure JDK 9+ Multiplatform Project with VarHandle Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Configure the atomicfu Gradle plugin for a JDK 9+ multiplatform project to use VarHandle for better performance. Set jvmVariant to "VH". ```gradle plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } atomicfu { dependenciesVersion = "0.33.0" jvmVariant = "VH" // VarHandle for better performance } ``` -------------------------------- ### Apply Legacy Gradle Plugin (Kotlin DSL) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Apply the kotlinx-atomicfu Gradle plugin using the legacy buildscript block in Kotlin DSL. ```kotlin buildscript { repositories { mavenCentral() } dependencies { classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.33.0") } } apply(plugin = "org.jetbrains.kotlinx.atomicfu") ``` -------------------------------- ### AtomicBoolean Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/types.md An atomic boolean type for thread-safe manipulation of boolean flags. It supports atomic setting, getting, and compare-and-setting of boolean values. ```APIDOC ## AtomicBoolean ### Description Atomic boolean type for thread-safe manipulation of boolean flags. Supports atomic setting, getting, and compare-and-setting of boolean values. ### Methods - `value: Boolean` - Gets or sets the current boolean value. - `lazySet(value: Boolean)` - Atomically sets the value, if it was not initialized yet. - `compareAndSet(expect: Boolean, update: Boolean): Boolean` - Atomically sets the value to `update` if the current value `== expect`. Returns `true` if successful. - `getAndSet(value: Boolean): Boolean` - Atomically sets the value to `value` and returns the old value. - `getValue(thisRef: Any?, property: KProperty<*>): Boolean` - Gets the current value using property delegation. - `setValue(thisRef: Any?, property: KProperty<*>, value: Boolean)` - Sets the value using property delegation. ### Extension Functions - `loop()` — Infinite loop - `update()` — Atomic update - `getAndUpdate()` — Update and return old - `updateAndGet()` — Update and return new ``` -------------------------------- ### Configure Legacy Maven Project Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Configure the atomicfu-maven-plugin for a legacy Maven project. Specify versions in properties and configure the kotlin-maven-plugin and atomicfu-maven-plugin executions. ```xml 0.33.0 2.2.0 org.jetbrains.kotlin kotlin-maven-plugin ${kotlin.version} compile ${project.build.directory}/classes-pre-atomicfu org.jetbrains.kotlinx atomicfu-maven-plugin ${atomicfu.version} transform ${project.build.directory}/classes-pre-atomicfu FU ``` -------------------------------- ### Use try-finally for Manual Locking Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Illustrates the correct pattern for manual locking using `try-finally`. This guarantees that the lock is always unlocked, even if exceptions occur. ```kotlin val lock = reentrantLock() fun manualLocking() { lock.lock() try { // critical section } finally { lock.unlock() // Always executes } } ``` -------------------------------- ### Update and Get Operations for Atomic References Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Employ `update`, `updateAndGet`, and `getAndUpdate` for idiomatic lock-free code when modifying atomic references. ```kotlin fun push(v: Value) = top.update { cur -> Node(v, cur) } fun pop(): Value? = top.getAndUpdate { cur -> cur?.next } ?.value ``` -------------------------------- ### Apply Legacy Gradle Plugin (Groovy DSL) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Apply the kotlinx-atomicfu Gradle plugin using the legacy buildscript block in Groovy DSL. ```groovy buildscript { repositories { mavenCentral() } dependencies { classpath 'org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.33.0' } } apply plugin: 'org.jetbrains.kotlinx.atomicfu' ``` -------------------------------- ### Get and Set AtomicBoolean value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-boolean.md Atomically sets the value to the given value and returns the old value. Useful for state transitions. ```kotlin private val completed = atomic(false) fun markCompleted(): Boolean { return completed.getAndSet(true) } ``` -------------------------------- ### Configure Atomicfu Build Script Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Configure atomicfu options, such as dependency versions, within the `atomicfu` section of your `build.gradle` file. ```groovy atomicfu { dependenciesVersion = '0.33.0' } ``` -------------------------------- ### Enable AtomicFU Build Scans Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Enable automatic upload of build scans to JetBrains Gradle Develocity server by setting properties in $GRADLE_USER_HOME/gradle.properties. Optionally provide a username. ```properties org.jetbrains.atomicfu.build.scan.enabled=true org.jetbrains.atomicfu.build.scan.username=John Doe ``` -------------------------------- ### Maven Configuration for Bytecode Transformation (Legacy) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Configuration for the `atomicfu-maven-plugin` to perform post-compilation bytecode transformation. This is a legacy approach and is limited to the JVM. ```xml org.jetbrains.kotlinx atomicfu-maven-plugin 0.33.0 transform ${project.build.directory}/classes-pre-atomicfu FU ``` -------------------------------- ### Valid Trace Size Initialization Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Creating a `Trace` with a size less than 1 will result in an `IllegalArgumentException`. Ensure the trace size is at least 1, with 32 being a recommended value. ```kotlin val trace = Trace(size = 1) val trace = Trace(size = 32) // Recommended ``` -------------------------------- ### Get and Set AtomicRef Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-ref.md Atomically sets the value of an AtomicRef and returns the previous value. Useful for operations that need to know the state before the update. ```kotlin private val current = atomic(null) fun setAndGetOld(newHandler: Handler): Handler? { return current.getAndSet(newHandler) } ``` -------------------------------- ### Maven Configuration for AtomicFu Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/INDEX.md Sets up the atomicfu-maven-plugin for a Maven project to enable the transformation process. Specifies the desired JVM variant. ```xml org.jetbrains.kotlinx atomicfu-maven-plugin 0.33.0 transform FU ``` -------------------------------- ### Configure Atomicfu Build Script with JVM and JS Options Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Configure atomicfu options including dependency versions, JVM transformation, and JVM variant. The `transformJs` flag is deprecated and has no effect. ```groovy atomicfu { dependenciesVersion = '0.33.0' // 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 } ``` -------------------------------- ### Gradle Plugin Application (Kotlin) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Apply the Kotlinx AtomicFU Gradle plugin in your top-level build file. Ensure you are using version 0.33.0 or later for the new plugin ID. ```kotlin plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } ``` -------------------------------- ### Get and Update AtomicBoolean atomically Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-boolean.md Atomically updates the value using a function and returns the old value before the update. Useful for operations that need the previous state. ```kotlin private val initialized = atomic(false) fun initializeOnce(): Boolean { return initialized.getAndUpdate { !it }.not() } ``` -------------------------------- ### Enable Gradle Build Scans Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Configuration to automatically enable and upload Gradle Build Scans for Atomicfu builds. Optionally, a username can be provided to be attached to each report. This is done by adding properties to the GRADLE_USER_HOME/gradle.properties file. ```properties org.jetbrains.atomicfu.build.scan.enabled=true # optionally provide a username that will be attached to each report org.jetbrains.atomicfu.build.scan.username=John Wick ``` -------------------------------- ### Gradle Configuration for AtomicFu Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/INDEX.md Configures the Kotlinx AtomicFu plugin and its dependencies for a Gradle project. Ensures the IR transformation is enabled for JVM. ```gradle plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } atomicfu { dependenciesVersion = "0.33.0" jvmVariant = "FU" // or "VH" for JDK 9+, "BOTH" for both } // gradle.properties kotlinx.atomicfu.enableJvmIrTransformation=true ``` -------------------------------- ### Enable Verbose Logging in Gradle Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Enable detailed logging for the atomicfu plugin within your Gradle build. This is done by setting a system property for the KaptGenerateStubsTask. ```gradle // Enable plugin logging tasks.withType(org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask.class) { systemProperties['kotlinx.atomicfu.debug'] = 'true' } ``` -------------------------------- ### AtomicFU Factory Functions Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Demonstrates how to create atomic variables using the overloaded atomic() factory functions for generic references and primitive types. ```kotlin // Generic reference fun atomic(initial: T, trace: TraceBase = TraceBase.None): AtomicRef // Primitive types fun atomic(initial: Int, trace: TraceBase = TraceBase.None): AtomicInt fun atomic(initial: Long, trace: TraceBase = TraceBase.None): AtomicLong fun atomic(initial: Boolean, trace: TraceBase = TraceBase.None): AtomicBoolean ``` -------------------------------- ### Build a Lock-Free Stack Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/00-START-HERE.md Illustrates the implementation of a lock-free stack using atomic operations for push and pop. This pattern is useful for concurrent data structures. ```kotlin private val head = atomic(null) fun push(value: String) { head.update { cur -> Node(value, cur) } } fun pop(): String? { return head.getAndUpdate { it?.next }?.value } ``` -------------------------------- ### AtomicRef Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/types.md Represents a generic atomic reference type for any non-primitive type. It supports basic operations like getting, setting, and compare-and-setting the value, as well as lazy initialization. ```APIDOC ## AtomicRef ### Description Generic atomic reference type for any non-primitive type. Supports basic operations like getting, setting, and compare-and-setting the value, as well as lazy initialization. ### Type Parameters - `T` — The type of value held atomically ### Methods - `value: T` - Gets or sets the current value. - `lazySet(value: T)` - Atomically sets the value, if it was not initialized yet. - `compareAndSet(expect: T, update: T): Boolean` - Atomically sets the value to `update` if the current value `== expect`. Returns `true` if successful. - `getAndSet(value: T): T` - Atomically sets the value to `value` and returns the old value. - `getValue(thisRef: Any?, property: KProperty<*>): T` - Gets the current value using property delegation. - `setValue(thisRef: Any?, property: KProperty<*>, value: T)` - Sets the value using property delegation. ### Extension Functions - `loop()` — Infinite loop over atomic value - `update()` — Atomic update from current value - `getAndUpdate()` — Update and return old value - `updateAndGet()` — Update and return new value ``` -------------------------------- ### Use reentrantLock with withLock Helper Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Demonstrates the correct pattern for using locks with the `withLock` helper. This ensures automatic lock release and simplifies critical section management. ```kotlin val lock = reentrantLock() fun safeOperation() { lock.withLock { // No manual lock/unlock needed } } ``` -------------------------------- ### Named Traces for Multiple Atomics Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Illustrates how to use named traces to distinguish operations on different atomic variables that share a common trace instance. This improves clarity in logs when tracking multiple related atomics. ```kotlin private val sharedTrace = Trace(size = 64) private val head = atomic(null, sharedTrace.named("head")) private val tail = atomic(null, sharedTrace.named("tail")) // Trace output clearly shows which atomic was modified ``` -------------------------------- ### Atomically Update AtomicRef and Get New Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-ref.md Use `updateAndGet()` to atomically update an AtomicRef and retrieve its value *after* the update. This is useful when the result of the update is immediately needed for further processing. ```kotlin public inline fun AtomicRef.updateAndGet(function: (T) -> T): T ``` ```kotlin private val config = atomic(Config.DEFAULT) fun updateConfig(transform: (Config) -> Config): Config { return config.updateAndGet(transform) } ``` -------------------------------- ### Custom Trace Formatting Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Configures a custom format for trace events, including index, event details, and nanosecond timestamp. ```kotlin val trace = Trace(format = TraceFormat { index, event -> "[$index] $event at ${System.nanoTime()}" }) ``` -------------------------------- ### Configure AtomicFU Maven Plugin Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Configure the atomicfu-maven-plugin for transformation, specifying input directory and transformation variant. ```xml org.jetbrains.kotlinx atomicfu-maven-plugin ${atomicfu.version} transform ${project.build.directory}/classes-pre-atomicfu FU ``` -------------------------------- ### AtomicBoolean updateAndGet Function Signature Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-boolean.md Shows the function signature for updating and getting the new value of an AtomicBoolean. It takes a lambda that computes the new boolean value based on the current one. ```kotlin public inline fun AtomicBoolean.updateAndGet(function: (Boolean) -> Boolean): Boolean ``` -------------------------------- ### Atomic Operations on Wasm (Boxed) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md WebAssembly support for AtomicFU is experimental. Atomics are not transformed and remain boxed objects at runtime, requiring the `atomicfu` library as a runtime dependency. ```kotlin // On Wasm, atomics remain boxed private val counter = atomic(0) // Still a boxed object at runtime ``` -------------------------------- ### AtomicFU Transformation Pipeline Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Shows the progression of atomic operations from user source code through compilation, IR transformation, and finally to JVM bytecode. ```text **Source Code (User)** ```kotlin private val counter = atomic(0) counter.value = x counter.compareAndSet(expect, update) ``` ↓ **After Compilation (Kotlin IR)** ```kotlin AtomicInt(0) // Still high-level representation ``` ↓ **After IR Transformation (Compiler Plugin)** ```kotlin volatile int counter_value AtomicIntegerFieldUpdater.setRelease(this, counter_value, x) AtomicIntegerFieldUpdater.compareAndSet(this, counter_value, expect, update) ``` ↓ **Bytecode Generation (JVM)** ```kotlin GETFIELD counter_value PUTFIELD counter_value INVOKESTATIC AtomicIntegerFieldUpdater.compareAndSet ``` ``` -------------------------------- ### Atomically Update AtomicRef and Get Old Value Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-ref.md Use `getAndUpdate()` to atomically update an AtomicRef and retrieve its value *before* the update. This is suitable for scenarios where you need to check the previous state or use it in subsequent logic. ```kotlin public inline fun AtomicRef.getAndUpdate(function: (T) -> T): T ``` ```kotlin private val state = atomic(State.IDLE) fun transition(newState: State): State { return state.getAndUpdate { oldState -> if (oldState.canTransitionTo(newState)) newState else oldState } } ``` -------------------------------- ### traceFormatDefault Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Provides the default trace formatter. This formatter can be configured via system properties to include additional context like thread names. ```APIDOC ## Properties ### traceFormatDefault The default trace formatter. ```kotlin public val traceFormatDefault: TraceFormat ``` **Type:** `TraceFormat` **Behavior:** On JVM, includes thread name in formatted messages if `kotlinx.atomicfu.trace.thread` system property is set. **Example:** ```kotlin // Enable thread names in traces System.setProperty("kotlinx.atomicfu.trace.thread", "true") val trace = Trace() // Now uses thread-aware formatter ``` ``` -------------------------------- ### Define Custom Trace Event Formatting Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Create a custom `TraceFormat` by providing a lambda to format trace events. This allows including additional context like timestamps or thread names in the trace output. ```kotlin public open class TraceFormat { public open fun format(index: Int, event: Any): String } ``` ```kotlin // Default format val defaultFormat = TraceFormat { index, event -> "$index: $event" } // Format with timestamp val timeFormat = TraceFormat { index, event -> val timestamp = SimpleDateFormat("HH:mm:ss.SSS").format(Date()) "$index [$timestamp] $event" } // Format with thread name val threadFormat = TraceFormat { index, event -> "$index [${Thread.currentThread().name}] $event" } val trace = Trace(size = 32, format = threadFormat) ``` ```kotlin @InlineOnly public inline fun TraceFormat( crossinline format: (index: Int, event: Any) -> String ): TraceFormat ``` ```kotlin val customFormat = TraceFormat { index, event -> "[${System.nanoTime()}] $index: $event" } val trace = Trace(size = 64, format = customFormat) ``` -------------------------------- ### Create Trace Object Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Creates a Trace object for recording atomic operations. You can specify the buffer size and a custom formatting function. The size is automatically rounded to the next power of 2. Use this when you need to log atomic operation history. ```kotlin import kotlinx.atomicfu.* // Create trace with default settings val trace = Trace() // Create trace with custom size (will be 64) val largeTrace = Trace(size = 50) // Create trace with custom formatting val traceWithThread = Trace(size = 32) { index, event -> "$index: [${Thread.currentThread().name}] $event" } // Use with atomic private val state = atomic(0, trace) // Call trace directly fun myFunction(x: Int) { trace { "Processing value: $x" } } ``` -------------------------------- ### Counter with Delegate Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md A concise way to implement a counter using an atomic variable and a property delegate. ```kotlin private val _count = atomic(0) public var count: Int by _count ``` -------------------------------- ### Create and Increment a Counter Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/00-START-HERE.md Demonstrates how to create an atomic integer and increment its value. Use this for thread-safe counting operations. ```kotlin import kotlinx.atomicfu.* private val count = atomic(0) fun increment() = count.incrementAndGet() // Returns new value fun get() = count.value ``` -------------------------------- ### Enable Post-Compilation Transformation (Legacy) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Enable the legacy post-compilation transformation for JVM. This is the default for Gradle versions older than 1.9. ```gradle transformJvm = true ``` -------------------------------- ### Configure Modern Kotlin Project with IR Transformation Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Configure the atomicfu Gradle plugin for a modern Kotlin project to use IR transformation. Set transformJvm to false and enable IR transformations via gradle.properties. ```gradle plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } atomicfu { dependenciesVersion = "0.33.0" transformJvm = false // Use IR instead } // In gradle.properties kotlinx.atomicfu.enableJvmIrTransformation=true kotlinx.atomicfu.enableNativeIrTransformation=true kotlinx.atomicfu.enableJsIrTransformation=true ``` -------------------------------- ### Lazy Atomic Initialization Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Defers the creation of expensive atomic objects until they are first accessed. This improves startup performance by avoiding unnecessary initialization. ```kotlin import kotlinx.atomicfu.* class Analyzer { private val _metrics = atomic(null) val metrics: Metrics get() { var m = _metrics.value if (m == null) { m = Metrics() _metrics.compareAndSet(null, m) } return _metrics.value!! // Guaranteed non-null after CAS } } data class Metrics(val startTime: Long = System.currentTimeMillis()) ``` -------------------------------- ### Fetch Latest Master Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/RELEASE.md Fetch the latest changes from the 'master' branch after the release merge. ```bash git fetch ``` -------------------------------- ### TraceFormat() Factory Function Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md Creates a custom trace formatter using a lambda function. This allows for flexible and context-aware formatting of trace messages. ```APIDOC ## Factory Function for TraceFormat ### TraceFormat() Creates a custom trace formatter. ```kotlin @InlineOnly public inline fun TraceFormat( crossinline format: (index: Int, event: Any) -> String ): TraceFormat ``` ### Parameters #### Path Parameters - **format** ( (Int, Any) -> String ) - Required - Formatting lambda ### Return type `TraceFormat` — Formatter object ### Example ```kotlin val customFormat = TraceFormat { index, event -> "[${System.nanoTime()}] $index: $event" } val trace = Trace(size = 64, format = customFormat) ``` ``` -------------------------------- ### Stress Testing Atomic Counter Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Demonstrates how to stress-test an atomic counter by concurrently incrementing it from multiple threads. Verifies the correctness of atomic operations under high load. ```kotlin import kotlinx.atomicfu.* import kotlin.concurrent.thread class StressTest { fun testCounter() { val counter = atomic(0) val threads = (0 until 100).map { thread { repeat(1000) { counter.incrementAndGet() } } } threads.forEach { it.join() } assert(counter.value == 100000) } } ``` -------------------------------- ### Configure JVM Variant to VH (VarHandle) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Configure the JVM variant to 'VH' in your Gradle build script to leverage VarHandle for atomic operations. This requires JDK 9 or newer and offers better performance on modern JVMs. ```gradle atomicfu { jvmVariant = "VH" } ``` ```kotlin private companion object { val HANDLE = MethodHandles.lookup() .findVarHandle(MyClass::class.java, "field", Int::class.java) } ``` -------------------------------- ### Enable JVM, Native, and JS IR Transformations Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/README.md Enable IR transformations for JVM, Native, and JS backends by setting these properties in your `gradle.properties` file. This is required for versions 0.24.0 and later with Kotlin 1.9.0+. ```groovy kotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation kotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformation kotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation ``` -------------------------------- ### TraceBase.None Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md A singleton NOP (No Operation) trace that does nothing. It is used as the default trace implementation when tracing is not needed, avoiding any overhead. ```APIDOC ## TraceBase.None ### Description A singleton NOP (No Operation) trace that does nothing. It is used as the default to avoid overhead when tracing is not needed. ### Class `public object None : TraceBase()` ### Example ```kotlin // Equivalent to not providing a trace val atomic1 = atomic(0, TraceBase.None) val atomic2 = atomic(0) // Uses None by default ``` ``` -------------------------------- ### Enable IR Transformation in Gradle Properties Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Configure kotlinx-atomicfu IR transformation for improved performance. Set these properties in your gradle.properties file for JVM, Native, and JS targets. ```properties kotlinx.atomicfu.enableJvmIrTransformation=true kotlinx.atomicfu.enableNativeIrTransformation=true kotlinx.atomicfu.enableJsIrTransformation=true ``` -------------------------------- ### Create AtomicBoolean with atomic() Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-atomic-boolean.md Creates an AtomicBoolean with an initial value. An optional trace object can be provided for recording modifications. ```kotlin import kotlinx.atomicfu.* // Simple flag private val isRunning = atomic(false) // With trace private val trace = Trace() private val isInitialized = atomic(false, trace) // As delegate private val _enabled = atomic(true) public var enabled: Boolean by _enabled ``` -------------------------------- ### Configure JVM Variant to BOTH (Multi-Release JAR) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/transformations-and-platform-details.md Set the JVM variant to 'BOTH' to create a single multi-release JAR that uses FieldUpdater on older JDKs and VarHandle on JDK 9+. This provides optimal performance and compatibility across different Java versions. ```gradle atomicfu { jvmVariant = "BOTH" } ``` ```text mylib.jar ├── META-INF/ │ └── versions/ │ └── 9/ │ └── com/example/MyClass.class (VarHandle variant) ├── com/example/MyClass.class (FieldUpdater variant) ``` -------------------------------- ### Inheritance-Based Synchronization with SynchronizedObject Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Provides simple, monitor-based synchronization similar to Java's synchronized keyword. Note that this is erased to `Any` on JS, offering no actual synchronization. ```kotlin import kotlinx.atomicfu.locks.* class DataHolder(initialValue: String) : SynchronizedObject() { private var data = initialValue fun update(newValue: String) { synchronized(this) { data = newValue } } fun get(): String = synchronized(this) { data } fun transform(fn: (String) -> String): String = synchronized(this) { data = fn(data) data } ``` -------------------------------- ### Atomic Configuration Updates Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Manage frequently changing configuration values atomically. Readers see the latest configuration immediately, and updates are atomic without locks. ```kotlin import kotlinx.atomicfu.* data class Config(val timeout: Long, val retries: Int, val debug: Boolean) class Service { private val _config = atomic(Config(5000L, 3, false)) val config: Config by _config // Read-only delegate fun updateConfig(newConfig: Config) { _config.value = newConfig // Atomic write } } ``` -------------------------------- ### Migrate from AtomicIntArray to kotlin.concurrent.atomics.AtomicIntArray Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Shows the migration from the deprecated AtomicIntArray to the standard library's AtomicIntArray. Ensure you use the correct replacement type for atomic arrays. ```kotlin // ❌ Old private val counters = AtomicIntArray(10) val value = counters[0].value // ✓ New private val counters = kotlin.concurrent.atomics.AtomicIntArray(10) val value = counters[0].value ``` -------------------------------- ### Reference-Based Atomic Operations for Linked Lists Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/usage-patterns-and-best-practices.md Demonstrates atomically swapping complex objects, specifically for managing a linked list structure. Allows for thread-safe insertion and searching. ```kotlin import kotlinx.atomicfu.* class Node(val value: T, var next: Node? = null) class LinkedList { private val head = atomic?>(null) fun insertAfter(node: Node, newNode: Node) { newNode.next = node.next node.next = newNode } fun find(predicate: (T) -> Boolean): Node? { var current = head.value while (current != null) { if (predicate(current.value)) return current current = current.next } return null } ``` -------------------------------- ### None Trace Object Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/api-reference-trace.md A singleton NOP (No Operation) trace that does nothing. It is used as the default when tracing is not needed, avoiding any overhead. ```kotlin // Equivalent to not providing a trace val atomic1 = atomic(0, TraceBase.None) val atomic2 = atomic(0) // Uses None by default ``` -------------------------------- ### Enable JVM IR Transformation (Gradle Property) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Enable IR-based JVM transformation using the Kotlin compiler plugin. This replaces the legacy post-compilation bytecode transformation. ```properties kotlinx.atomicfu.enableJvmIrTransformation=true ``` -------------------------------- ### Declare AtomicFU Plugin in Gradle Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/errors.md Ensures the AtomicFU Gradle plugin is declared in your build.gradle file. This is necessary for build success and proper transformation. ```gradle plugins { id("org.jetbrains.kotlinx.atomicfu") version "0.33.0" } ``` -------------------------------- ### AtomicFU getAndUpdate() Extension Function Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/overview.md Demonstrates the getAndUpdate() extension function, which atomically updates the value and returns the old value before the update. ```kotlin val oldValue = counter.getAndUpdate { it + 1 } ``` -------------------------------- ### Set AtomicFU Dependencies Version (Gradle Build Script) Source: https://github.com/kotlin/kotlinx-atomicfu/blob/master/_autodocs/configuration.md Configure the version for the auto-managed atomicfu library dependency. Set to null to disable auto-dependency management. ```gradle atomicfu { dependenciesVersion = "0.33.0" } ```