diff --git a/build.gradle.kts b/build.gradle.kts index 28dec83..9b03cc9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -59,7 +59,6 @@ xomrk { val commonMain by getting { dependencies { compileOnly(kotlinStdlibDependency) - implementation("org.jetbrains.kotlinx:atomicfu:0.27.0") implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.5") } } @@ -73,6 +72,7 @@ xomrk { dependsOn(commonMain) dependencies { implementation(kotlinStdlibDependency) + implementation("org.jetbrains.kotlinx:atomicfu:0.27.0") } } diff --git a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter.kt b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter.kt index 1402ad0..14be613 100644 --- a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter.kt +++ b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter.kt @@ -5,14 +5,11 @@ package ru.landrafhomyak.utility.reference_counter import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract -import kotlinx.atomicfu.AtomicLong -import kotlinx.atomicfu.atomic -import kotlinx.atomicfu.update import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1 import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2 public class CloseableReferenceCounter(private val _errMessage: String) { - private val _value: AtomicLong = atomic(0L) + private val _value = _AtomicLong(0L) public fun throwClosed() { throw IllegalStateException(this._errMessage) @@ -34,7 +31,7 @@ public class CloseableReferenceCounter(private val _errMessage: String) { } public fun assertNotClosed() { - if (this._value.value < 0) this.throwClosed() + if (this._value.get() < 0) this.throwClosed() } public fun decref() { @@ -63,7 +60,7 @@ public class CloseableReferenceCounter(private val _errMessage: String) { } override fun toString(): String { - val refcntCached = this._value.value + val refcntCached = this._value.get() @Suppress("LiftReturnOrAssignment") if (refcntCached < 0) return "" diff --git a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter_Debug.kt b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter_Debug.kt index 298f3ec..bd6b791 100644 --- a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter_Debug.kt +++ b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/CloseableReferenceCounter_Debug.kt @@ -5,10 +5,6 @@ package ru.landrafhomyak.utility.reference_counter import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract -import kotlinx.atomicfu.AtomicLong -import kotlinx.atomicfu.atomic -import kotlinx.atomicfu.getAndUpdate -import kotlinx.atomicfu.update import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose1 import ru.landgrafhomyak.utility.highlevel_try_finally.safeAutoClose2 @@ -27,10 +23,10 @@ public class CloseableReferenceCounter_Debug( public annotation class RequiresExplicitDebug - private val _value: AtomicLong = atomic(0L) + private val _value = _AtomicLong(0L) @Suppress("RemoveRedundantQualifierName") - private val _id = CloseableReferenceCounter_Debug._nextId.getAndUpdate(ULong::inc) + private val _id = CloseableReferenceCounter_Debug._nextId.getAndUpdate(Long::inc) @Suppress("NOTHING_TO_INLINE") private inline fun _throwErrors(valueToCheck: Long) { @@ -43,7 +39,7 @@ public class CloseableReferenceCounter_Debug( @RequiresExplicitDebug public fun throwErrors() { - this._throwErrors(this._value.value) + this._throwErrors(this._value.get()) } public fun throwClosed() { @@ -71,7 +67,7 @@ public class CloseableReferenceCounter_Debug( } public fun assertNotClosed() { - if (this._value.value < 0) this.throwClosed() + if (this._value.get() < 0) this.throwClosed() } public fun decref() { @@ -110,7 +106,7 @@ public class CloseableReferenceCounter_Debug( } override fun toString(): String { - val refcntCached = this._value.value + val refcntCached = this._value.get() val stateRepr: String @Suppress("LiftReturnOrAssignment") when { @@ -124,7 +120,7 @@ public class CloseableReferenceCounter_Debug( } public companion object { - private val _nextId = atomic(0uL) + private val _nextId = _AtomicLong(0L) } public object ObserveToStdout : Observer { diff --git a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt new file mode 100644 index 0000000..c1e1ac1 --- /dev/null +++ b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt @@ -0,0 +1,13 @@ +package ru.landrafhomyak.utility.reference_counter + +internal expect class _AtomicLong { + constructor(initial: Long) + + fun get(): Long + + inline fun update(operator: (Long) -> Long) + + inline fun getAndUpdate(operator: (Long) -> Long):Long + + fun compareAndSet(expected: Long, newValue: Long): Boolean +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_CloseableReferenceCounter_LowLevel.kt b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_CloseableReferenceCounter_LowLevel.kt index 3ca6a20..e069e25 100644 --- a/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_CloseableReferenceCounter_LowLevel.kt +++ b/src/commonMain/kotlin/ru/landrafhomyak/utility/reference_counter/_CloseableReferenceCounter_LowLevel.kt @@ -1,12 +1,10 @@ package ru.landrafhomyak.utility.reference_counter -import kotlinx.atomicfu.AtomicLong - @Suppress("ClassName") internal object _CloseableReferenceCounter_LowLevel { - internal fun compareAndExchange(atomic: AtomicLong, expected: Long, newValue: Long): Long { + internal fun compareAndExchange(atomic: _AtomicLong, expected: Long, newValue: Long): Long { while (true) { - val old = atomic.value + val old = atomic.get() if (old != expected) return old if (atomic.compareAndSet(old, newValue)) return old } diff --git a/src/jvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt b/src/jvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt new file mode 100644 index 0000000..dd4eb55 --- /dev/null +++ b/src/jvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt @@ -0,0 +1,32 @@ +package ru.landrafhomyak.utility.reference_counter + +import java.util.concurrent.atomic.AtomicLong + +internal actual /*value*/ class _AtomicLong { + private val _native: AtomicLong + + actual constructor(initial: Long) { + this._native = AtomicLong(initial) + } + + actual fun get() = this._native.get() + + actual inline fun update(operator: (Long) -> Long) { + while (true) { + val cur = this._native.get() + val upd = operator(cur) + if (this._native.compareAndSet(cur, upd)) return + } + } + + actual inline fun getAndUpdate(operator: (Long) -> Long): Long { + while (true) { + val cur = this._native.get() + val upd = operator(cur) + if (this._native.compareAndSet(cur, upd)) return cur + } + } + + actual fun compareAndSet(expected: Long, newValue: Long): Boolean = + this._native.compareAndSet(expected, newValue) +} \ No newline at end of file diff --git a/src/nonJvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt b/src/nonJvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt new file mode 100644 index 0000000..f26768a --- /dev/null +++ b/src/nonJvmMain/kotlin/ru/landrafhomyak/utility/reference_counter/_AtomicLong.kt @@ -0,0 +1,26 @@ +package ru.landrafhomyak.utility.reference_counter + +import kotlinx.atomicfu.AtomicLong +import kotlinx.atomicfu.atomic +import kotlinx.atomicfu.getAndUpdate +import kotlinx.atomicfu.update + +internal actual class _AtomicLong { + val _atomicfu: AtomicLong + + actual constructor(initial: Long) { + this._atomicfu = atomic(0L) + } + + actual fun get() = + this._atomicfu.value + + actual inline fun update(operator: (Long) -> Long) = + this._atomicfu.update(operator) + + actual inline fun getAndUpdate(operator: (Long) -> Long) = + this._atomicfu.getAndUpdate(operator) + + actual fun compareAndSet(expected: Long, newValue: Long): Boolean = + this._atomicfu.compareAndSet(expected, newValue) +} \ No newline at end of file