All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.kotlinx.atomicfu.AtomicFU.kt Maven / Gradle / Ivy

There is a newer version: 0.26.1
Show newest version
/*
 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

@file:JvmName("AtomicFU")
@file:Suppress("NOTHING_TO_INLINE", "RedundantVisibilityModifier", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")

package kotlinx.atomicfu

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater
import java.util.concurrent.atomic.AtomicLongFieldUpdater
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
import kotlin.reflect.KProperty
import kotlinx.atomicfu.TraceBase.None
import kotlin.internal.InlineOnly

/**
 * Creates atomic reference with a given [initial] value.
 *
 * It can only be used in initialize of private read-only property, like this:
 *
 * ```
 * private val f = atomic(initial)
 * ```
 */
public actual fun  atomic(initial: T, trace: TraceBase): AtomicRef = AtomicRef(initial, trace)

public actual fun  atomic(initial: T): AtomicRef = atomic(initial, None)

/**
 * Creates atomic [Int] with a given [initial] value.
 *
 * It can only be used in initialize of private read-only property, like this:
 *
 * ```
 * private val f = atomic(initialInt)
 * ```
 */
public actual fun atomic(initial: Int, trace: TraceBase): AtomicInt = AtomicInt(initial, trace)

public actual fun atomic(initial: Int): AtomicInt = atomic(initial, None)

/**
 * Creates atomic [Long] with a given [initial] value.
 *
 * It can only be used in initialize of private read-only property, like this:
 *
 * ```
 * private val f = atomic(initialLong)
 * ```
 */
public actual fun atomic(initial: Long, trace: TraceBase): AtomicLong = AtomicLong(initial, trace)

public actual fun atomic(initial: Long): AtomicLong = atomic(initial, None)

/**
 * Creates atomic [Boolean] with a given [initial] value.
 *
 * It can only be used in initialize of private read-only property, like this:
 *
 * ```
 * private val f = atomic(initialBoolean)
 * ```
 */
public actual fun atomic(initial: Boolean, trace: TraceBase): AtomicBoolean = AtomicBoolean(initial, trace)

public actual fun atomic(initial: Boolean): AtomicBoolean = atomic(initial, None)

// ==================================== AtomicRef ====================================

/**
 * Atomic reference to a variable of type [T] with volatile reads/writes via
 * [value] property and various atomic read-modify-write operations
 * like [compareAndSet] and others.
 */
@Suppress("UNCHECKED_CAST")
public actual class AtomicRef internal constructor(value: T, val trace: TraceBase) {
    /**
     * Reading/writing this property maps to read/write of volatile variable.
     */
    @Volatile
    public actual var value: T = value
        set(value) {
            field = value
            if (trace !== None) trace { "set($value)" }
        }

    @InlineOnly
    public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value

    @InlineOnly
    public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { this.value = value }

    /**
     * Maps to [AtomicReferenceFieldUpdater.lazySet].
     */
    public actual fun lazySet(value: T) {
        FU.lazySet(this, value)
        if (trace !== None) trace { "lazySet($value)" }
    }

    /**
     * Maps to [AtomicReferenceFieldUpdater.compareAndSet].
     */
    public actual fun compareAndSet(expect: T, update: T): Boolean {
        val result = FU.compareAndSet(this, expect, update)
        if (result && trace !== None) trace { "CAS($expect, $update)" }
        return result
    }

    /**
     * Maps to [AtomicReferenceFieldUpdater.getAndSet].
     */
    public actual fun getAndSet(value: T): T {
        val oldValue = FU.getAndSet(this, value) as T
        if (trace !== None) trace { "getAndSet($value):$oldValue" }
        return oldValue
    }

    override fun toString(): String = value.toString()

    private companion object {
        private val FU = AtomicReferenceFieldUpdater.newUpdater(AtomicRef::class.java, Any::class.java, "value")
    }
}


// ==================================== AtomicBoolean ====================================

/**
 * Atomic reference to an [Boolean] variable with volatile reads/writes via
 * [value] property and various atomic read-modify-write operations
 * like [compareAndSet] and others.
 */
@Suppress("UNCHECKED_CAST")
public actual class AtomicBoolean internal constructor(v: Boolean, val trace: TraceBase) {

    @Volatile
    private var _value: Int = if (v) 1 else 0

    @InlineOnly
    public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Boolean = value

    @InlineOnly
    public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) { this.value = value }

    /**
     * Reading/writing this property maps to read/write of volatile variable.
     */
    public actual var value: Boolean
        get() = _value != 0
        set(value) {
            _value = if (value) 1 else 0
            if (trace !== None) trace { "set($value)" }
        }

    /**
     * Maps to [AtomicIntegerFieldUpdater.lazySet].
     */
    public actual fun lazySet(value: Boolean) {
        val v = if (value) 1 else 0
        FU.lazySet(this, v)
        if (trace !== None) trace { "lazySet($value)" }
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.compareAndSet].
     */
    public actual fun compareAndSet(expect: Boolean, update: Boolean): Boolean {
        val e = if (expect) 1 else 0
        val u = if (update) 1 else 0
        val result = FU.compareAndSet(this, e, u)
        if (result && trace !== None) trace { "CAS($expect, $update)" }
        return result
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.getAndSet].
     */
    public actual fun getAndSet(value: Boolean): Boolean {
        val v = if (value) 1 else 0
        val oldValue = FU.getAndSet(this, v)
        if (trace !== None) trace { "getAndSet($value):$oldValue" }
        return oldValue == 1
    }

    override fun toString(): String = value.toString()

    private companion object {
        private val FU = AtomicIntegerFieldUpdater.newUpdater(AtomicBoolean::class.java, "_value")
    }
}

// ==================================== AtomicInt ====================================

/**
 * Atomic reference to an [Int] variable with volatile reads/writes via
 * [value] property and various atomic read-modify-write operations
 * like [compareAndSet] and others.
 */
public actual class AtomicInt internal constructor(value: Int, val trace: TraceBase) {
    /**
     * Reads/writes of this property maps to read/write of volatile variable.
     */
    @Volatile
    public actual var value: Int = value
        set(value) {
            field = value
            if (trace !== None) trace { "set($value)" }
        }

    @InlineOnly
    public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Int = value

    @InlineOnly
    public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { this.value = value }

    /**
     * Maps to [AtomicIntegerFieldUpdater.lazySet].
     */
    public actual fun lazySet(value: Int) {
        FU.lazySet(this, value)
        if (trace !== None) trace { "lazySet($value)" }
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.compareAndSet].
     */
    public actual fun compareAndSet(expect: Int, update: Int): Boolean {
        val result = FU.compareAndSet(this, expect, update)
        if (result && trace !== None) trace { "CAS($expect, $update)" }
        return result
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.getAndSet].
     */
    public actual fun getAndSet(value: Int): Int {
        val oldValue = FU.getAndSet(this, value)
        if (trace !== None) trace { "getAndSet($value):$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.getAndIncrement].
     */
    public actual fun getAndIncrement(): Int {
        val oldValue = FU.getAndIncrement(this)
        if (trace !== None) trace { "getAndInc():$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.getAndDecrement].
     */
    public actual fun getAndDecrement(): Int {
        val oldValue = FU.getAndDecrement(this)
        if (trace !== None) trace { "getAndDec():$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.getAndAdd].
     */
    public actual fun getAndAdd(delta: Int): Int {
        val oldValue = FU.getAndAdd(this, delta)
        if (trace !== None) trace { "getAndAdd($delta):$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.addAndGet].
     */
    public actual fun addAndGet(delta: Int): Int {
        val newValue = FU.addAndGet(this, delta)
        if (trace !== None) trace { "addAndGet($delta):$newValue" }
        return newValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.incrementAndGet].
     */
    public actual fun incrementAndGet(): Int {
        val newValue = FU.incrementAndGet(this)
        if (trace !== None) trace { "incAndGet():$newValue" }
        return newValue
    }

    /**
     * Maps to [AtomicIntegerFieldUpdater.decrementAndGet].
     */
    public actual fun decrementAndGet(): Int {
        val newValue = FU.decrementAndGet(this)
        if (trace !== None) trace { "decAndGet():$newValue" }
        return newValue
    }

    /**
     * Performs atomic addition of [delta].
     */
    public actual inline operator fun plusAssign(delta: Int) {
        getAndAdd(delta)
    }

    /**
     * Performs atomic subtraction of [delta].
     */
    public actual inline operator fun minusAssign(delta: Int) {
        getAndAdd(-delta)
    }

    override fun toString(): String = value.toString()

    private companion object {
        private val FU = AtomicIntegerFieldUpdater.newUpdater(AtomicInt::class.java, "value")
    }
}

// ==================================== AtomicLong ====================================

/**
 * Atomic reference to a [Long] variable with volatile reads/writes via
 * [value] property and various atomic read-modify-write operations
 * like [compareAndSet] and others.
 */
public actual class AtomicLong internal constructor(value: Long, val trace: TraceBase) {
    /**
     * Reads/writes of this property maps to read/write of volatile variable.
     */
    @Volatile
    public actual var value: Long = value
        set(value) {
            field = value
            if (trace !== None) trace { "set($value)" }
        }

    @InlineOnly
    public actual inline operator fun getValue(thisRef: Any?, property: KProperty<*>): Long = value

    @InlineOnly
    public actual inline operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Long) { this.value = value }

    /**
     * Maps to [AtomicLongFieldUpdater.lazySet].
     */
    public actual fun lazySet(value: Long) {
        FU.lazySet(this, value)
        if (trace !== None) trace { "lazySet($value)" }
    }

    /**
     * Maps to [AtomicLongFieldUpdater.compareAndSet].
     */
    public actual fun compareAndSet(expect: Long, update: Long): Boolean {
        val result = FU.compareAndSet(this, expect, update)
        if (result && trace !== None) trace { "CAS($expect, $update)" }
        return result
    }

    /**
     * Maps to [AtomicLongFieldUpdater.getAndSet].
     */
    public actual fun getAndSet(value: Long): Long {
        val oldValue = FU.getAndSet(this, value)
        if (trace !== None) trace { "getAndSet($value):$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.getAndIncrement].
     */
    public actual fun getAndIncrement(): Long {
        val oldValue = FU.getAndIncrement(this)
        if (trace !== None) trace { "getAndInc():$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.getAndDecrement].
     */
    public actual fun getAndDecrement(): Long {
        val oldValue = FU.getAndDecrement(this)
        if (trace !== None) trace { "getAndDec():$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.getAndAdd].
     */
    public actual fun getAndAdd(delta: Long): Long {
        val oldValue = FU.getAndAdd(this, delta)
        if (trace !== None) trace { "getAndAdd($delta):$oldValue" }
        return oldValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.addAndGet].
     */
    public actual fun addAndGet(delta: Long): Long {
        val newValue = FU.addAndGet(this, delta)
        if (trace !== None) trace { "addAndGet($delta):$newValue" }
        return newValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.incrementAndGet].
     */
    public actual fun incrementAndGet(): Long {
        val newValue = FU.incrementAndGet(this)
        if (trace !== None) trace { "incAndGet():$newValue" }
        return newValue
    }

    /**
     * Maps to [AtomicLongFieldUpdater.decrementAndGet].
     */
    public actual fun decrementAndGet(): Long {
        val newValue = FU.decrementAndGet(this)
        if (trace !== None) trace { "decAndGet():$newValue" }
        return newValue
    }

    /**
     * Performs atomic addition of [delta].
     */
    public actual inline operator fun plusAssign(delta: Long) {
        getAndAdd(delta)
    }

    /**
     * Performs atomic subtraction of [delta].
     */
    public actual inline operator fun minusAssign(delta: Long) {
        getAndAdd(-delta)
    }

    override fun toString(): String = value.toString()

    private companion object {
        private val FU = AtomicLongFieldUpdater.newUpdater(AtomicLong::class.java, "value")
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy