From 7131a38bd485ff420cd7b87c6a9b7a44f78051b9 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Sun, 24 Aug 2025 03:59:16 +0300 Subject: [PATCH] Removed excess atomic functions and minor fixes --- .../closeable_state_1/_MiscMultiplatform.kt | 5 + .../closeable_state_1/internal/atomics.kt | 27 ---- .../jErrorOnConcurrentAccessState.java | 4 +- .../closeable_state_1/jUsagesCounter.java | 8 +- .../closeable_state_1/internal/atomics.kt | 124 ------------------ .../ErrorOnConcurrentAccessState.kt | 17 ++- .../closeable_state_1/UsagesCounter.kt | 22 ++-- .../utility/closeable_state_1/_MiscNonJvm.kt | 24 ++++ .../closeable_state_1/internal/atomics.kt | 77 ----------- 9 files changed, 53 insertions(+), 255 deletions(-) create mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscMultiplatform.kt delete mode 100644 src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt delete mode 100644 src/jvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt create mode 100644 src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscNonJvm.kt delete mode 100644 src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscMultiplatform.kt b/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscMultiplatform.kt new file mode 100644 index 0000000..b93f624 --- /dev/null +++ b/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscMultiplatform.kt @@ -0,0 +1,5 @@ +package ru.landgrafhomyak.utility.closeable_state_1 + +internal object _MiscMultiplatform { + internal const val CLOSED_STATE_VALUE = -0x4000_0000_0000_0000L +} \ No newline at end of file diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt b/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt deleted file mode 100644 index 07d1081..0000000 --- a/src/commonMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt +++ /dev/null @@ -1,27 +0,0 @@ -@file:JvmName("AtomicsKt") - -package ru.landgrafhomyak.utility.closeable_state_1.internal - -import kotlin.jvm.JvmName - - -internal expect class AtomicLong -internal expect class AtomicReference - -internal expect inline fun newAtomicLong(initial: Long): AtomicLong -internal expect inline fun newAtomicRef(initial: T): AtomicReference - -internal expect inline fun AtomicLong.get(): Long -internal expect inline fun AtomicReference.get(): T - -internal expect inline fun AtomicLong.update(operator: (Long) -> Long) -internal expect inline fun AtomicReference.update(operator: (T) -> T) - -internal expect inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long -internal expect inline fun AtomicReference.getAndUpdate(operator: (T) -> T): T - -internal expect inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean -internal expect inline fun AtomicReference.compareAndSet(expected: T, newValue: T): Boolean - -internal expect inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long -internal expect inline fun AtomicReference.compareAndExchange(expected: T, newValue: T): T \ No newline at end of file diff --git a/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jErrorOnConcurrentAccessState.java b/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jErrorOnConcurrentAccessState.java index 63bc861..1faa414 100644 --- a/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jErrorOnConcurrentAccessState.java +++ b/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jErrorOnConcurrentAccessState.java @@ -13,7 +13,7 @@ public /* open */ class jErrorOnConcurrentAccessState private final AtomicReference _currentState; public jErrorOnConcurrentAccessState() { - this._currentState = new AtomicReference<>(); + this._currentState = new AtomicReference<>(State.OPEN); } @Override @@ -74,7 +74,7 @@ public /* open */ class jErrorOnConcurrentAccessState case IN_USE: return ""; case OPEN: - return ""; + return ""; } throw new RuntimeException("Unreachable"); } diff --git a/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jUsagesCounter.java b/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jUsagesCounter.java index 61a5695..348ece1 100644 --- a/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jUsagesCounter.java +++ b/src/jvmMain/java/ru/landgrafhomyak/utility/closeable_state_1/jUsagesCounter.java @@ -1,10 +1,10 @@ package ru.landgrafhomyak.utility.closeable_state_1; -import ru.landgrafhomyak.utility.closeable_state_1.internal.Misc; - import java.util.concurrent.atomic.AtomicLong; -public /* open */ class jUsagesCounter extends jUsagesCounter$Errors implements CloseableState.AllowsConcurrency { +public /* open */ class jUsagesCounter + extends jUsagesCounter$Errors + implements CloseableState.AllowsConcurrency { private final AtomicLong _currentUsagesCount; public jUsagesCounter() { @@ -56,7 +56,7 @@ public /* open */ class jUsagesCounter extends jUsagesCounter$Errors implements while (true) { currentReferencesCount = this._currentUsagesCount.get(); if (currentReferencesCount != 0) break; - if (this._currentUsagesCount.compareAndSet(currentReferencesCount, Misc.CLOSED_STATE_VALUE)) + if (this._currentUsagesCount.compareAndSet(currentReferencesCount, _MiscMultiplatform.CLOSED_STATE_VALUE)) break; } diff --git a/src/jvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt b/src/jvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt deleted file mode 100644 index 447a416..0000000 --- a/src/jvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt +++ /dev/null @@ -1,124 +0,0 @@ -@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE") -@file:JvmName("AtomicsKt") - -package ru.landgrafhomyak.utility.closeable_state_1.internal - -import java.util.concurrent.atomic.AtomicLong as jAtomicLong -import java.util.concurrent.atomic.AtomicReference as jAtomicReference -import kotlin.jvm.JvmName - - -internal actual typealias AtomicLong = jAtomicLong -internal actual typealias AtomicReference = jAtomicReference - - -internal actual inline fun newAtomicLong(initial: Long): AtomicLong = - jAtomicLong(initial) - -internal actual inline fun newAtomicRef(initial: T): AtomicReference = - jAtomicReference(initial) - - -internal actual inline fun AtomicLong.get(): Long = - (this as jAtomicLong).get() - -internal actual inline fun AtomicReference.get(): T = - (this as jAtomicReference).get() - - -internal actual inline fun AtomicLong.update(operator: (Long) -> Long) { - val a = (this as jAtomicLong) - Misc._getAndUpdate( - get = a::get, - cas = a::compareAndSet, - operator = operator - ) -} - -internal actual inline fun AtomicReference.update(operator: (T) -> T) { - val a = (this as jAtomicReference) - Misc._getAndUpdate( - get = a::get, - cas = a::compareAndSet, - operator = operator - ) -} - -internal actual inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long { - val a = (this as jAtomicLong) - return Misc._getAndUpdate( - get = a::get, - cas = a::compareAndSet, - operator = operator - ) -} - -internal actual inline fun AtomicReference.getAndUpdate(operator: (T) -> T): T { - val a = (this as jAtomicReference) - return Misc._getAndUpdate( - get = a::get, - cas = a::compareAndSet, - operator = operator - ) -} - - -internal actual inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean = - (this as jAtomicLong).compareAndSet(expected, newValue) - -internal actual inline fun AtomicReference.compareAndSet(expected: T, newValue: T): Boolean = - (this as jAtomicReference).compareAndSet(expected, newValue) - - -private fun AtomicLong.`compareAndExchange$custom`(expected: Long, newValue: Long): Long { - val a = (this as jAtomicLong) - return Misc._compareAndExchange( - get = a::get, - cas = a::compareAndSet, - expected = expected, newValue = newValue - ) -} - - -private fun AtomicReference.`compareAndExchange$custom`(expected: T, newValue: T): T { - val a = (this as jAtomicReference) - return Misc._compareAndExchange( - get = a::get, - cas = a::compareAndSet, - expected = expected, newValue = newValue - ) -} - -internal actual inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long { - if (_long_isNativeCompareAndExchangeExists) - return (this as jAtomicLong).compareAndExchange(expected, newValue) - else - return this.`compareAndExchange$custom`(expected, newValue) -} - -internal actual inline fun AtomicReference.compareAndExchange(expected: T, newValue: T): T { - if (_ref_isNativeCompareAndExchangeExists) - return (this as jAtomicReference).compareAndExchange(expected, newValue) - else - return this.`compareAndExchange$custom`(expected, newValue) -} - -private val _long_isNativeCompareAndExchangeExists = run { - val a = jAtomicLong() - try { - a.compareAndExchange(0, 0) - return@run true - } catch (_: NoSuchMethodError) { - return@run false - } -} - -private val _ref_isNativeCompareAndExchangeExists = run { - val a = jAtomicReference() - try { - a.compareAndExchange(null, null) - return@run true - } catch (_: NoSuchMethodError) { - return@run false - } -} \ No newline at end of file diff --git a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/ErrorOnConcurrentAccessState.kt b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/ErrorOnConcurrentAccessState.kt index 50e5e69..9c5bb04 100644 --- a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/ErrorOnConcurrentAccessState.kt +++ b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/ErrorOnConcurrentAccessState.kt @@ -1,18 +1,17 @@ package ru.landgrafhomyak.utility.closeable_state_1 -import ru.landgrafhomyak.utility.closeable_state_1.internal.compareAndExchange -import ru.landgrafhomyak.utility.closeable_state_1.internal.get -import ru.landgrafhomyak.utility.closeable_state_1.internal.newAtomicRef +import kotlinx.atomicfu.atomic +import ru.landgrafhomyak.utility.closeable_state_1._MiscNonJvm.compareAndExchange public actual open class ErrorOnConcurrentAccessState : CloseableState.ExternallySynchronized { private enum class State { OPEN, IN_USE, CLOSED } - private val _state = newAtomicRef(State.OPEN) + private val _state = atomic(State.OPEN) public actual final override val isInUse: Boolean - get() = this._state.get() === State.IN_USE + get() = this._state.value === State.IN_USE protected actual open fun throwClosed(): Nothing { throw IllegalStateException("Object is closed") @@ -27,12 +26,12 @@ public actual open class ErrorOnConcurrentAccessState : CloseableState.Externall } public actual final override fun assertNotClosed() { - if (this._state.get() === State.CLOSED) + if (this._state.value === State.CLOSED) this.throwClosed() } public actual final override val isClosed: Boolean - get() = this._state.get() === State.CLOSED + get() = this._state.value === State.CLOSED @ManualStateManipulation public actual final override fun startUsage() { @@ -64,9 +63,9 @@ public actual open class ErrorOnConcurrentAccessState : CloseableState.Externall @Suppress("RedundantModalityModifier") public actual open override fun toString(): String = - when (this._state.get()) { + when (this._state.value) { State.OPEN -> "" State.IN_USE -> "" - State.CLOSED -> "" + State.CLOSED -> "" } } \ No newline at end of file diff --git a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/UsagesCounter.kt b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/UsagesCounter.kt index dd5d701..a1302fc 100644 --- a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/UsagesCounter.kt +++ b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/UsagesCounter.kt @@ -3,19 +3,17 @@ package ru.landgrafhomyak.utility.closeable_state_1 import kotlin.contracts.ExperimentalContracts -import ru.landgrafhomyak.utility.closeable_state_1.internal.AtomicLong -import ru.landgrafhomyak.utility.closeable_state_1.internal.Misc -import ru.landgrafhomyak.utility.closeable_state_1.internal.compareAndExchange -import ru.landgrafhomyak.utility.closeable_state_1.internal.get -import ru.landgrafhomyak.utility.closeable_state_1.internal.newAtomicLong -import ru.landgrafhomyak.utility.closeable_state_1.internal.update +import kotlinx.atomicfu.AtomicLong +import kotlinx.atomicfu.atomic +import kotlinx.atomicfu.update +import ru.landgrafhomyak.utility.closeable_state_1._MiscNonJvm.compareAndExchange public actual open class UsagesCounter : CloseableState.AllowsConcurrency { - private val _value: AtomicLong = newAtomicLong(0L) + private val _value: AtomicLong = atomic(0L) public actual constructor() - public fun getCurrentUsagesCount(): Long = this._value.get() + public fun getCurrentUsagesCount(): Long = this._value.value protected actual open fun throwClosed(): Nothing { throw IllegalStateException("Object is closed") @@ -26,10 +24,10 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency { } - public actual final override val isClosed: Boolean get() = this._value.get() < 0 + public actual final override val isClosed: Boolean get() = this._value.value < 0 public actual final override fun assertNotClosed() { - if (this._value.get() < 0) this.throwClosed() + if (this._value.value < 0) this.throwClosed() } @ManualStateManipulation @@ -47,7 +45,7 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency { @ManualStateManipulation public actual final override fun close() { - val state = this._value.compareAndExchange(0, Misc.CLOSED_STATE_VALUE) + val state = this._value.compareAndExchange(0, _MiscMultiplatform.CLOSED_STATE_VALUE) when { state > 0 -> this.throwInUse() state < 0 -> this.throwClosed() @@ -56,7 +54,7 @@ public actual open class UsagesCounter : CloseableState.AllowsConcurrency { @Suppress("RedundantModalityModifier") public actual open override fun toString(): String { - val cached = this._value.get() + val cached = this._value.value @Suppress("LiftReturnOrAssignment") if (cached < 0) return "" diff --git a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscNonJvm.kt b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscNonJvm.kt new file mode 100644 index 0000000..4c63f9f --- /dev/null +++ b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/_MiscNonJvm.kt @@ -0,0 +1,24 @@ +package ru.landgrafhomyak.utility.closeable_state_1 + +import kotlin.jvm.JvmStatic +import kotlinx.atomicfu.AtomicLong +import kotlinx.atomicfu.AtomicRef +import kotlinx.atomicfu.getAndUpdate + +internal object _MiscNonJvm { + @JvmStatic + internal fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long { + return this.getAndUpdate { old -> + if (old != expected) return@compareAndExchange old + return@getAndUpdate newValue + } + } + + @JvmStatic + internal fun AtomicRef.compareAndExchange(expected: T, newValue: T): T { + return this.getAndUpdate { old -> + if (old != expected) return@compareAndExchange old + return@getAndUpdate newValue + } + } +} \ No newline at end of file diff --git a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt b/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt deleted file mode 100644 index 4d14076..0000000 --- a/src/nonJvmMain/kotlin/ru/landgrafhomyak/utility/closeable_state_1/internal/atomics.kt +++ /dev/null @@ -1,77 +0,0 @@ -@file:Suppress("USELESS_CAST", "NOTHING_TO_INLINE") -@file:JvmName("AtomicsKt") - -package ru.landgrafhomyak.utility.closeable_state_1.internal - -import kotlin.jvm.JvmName -import kotlinx.atomicfu.atomic -import kotlinx.atomicfu.AtomicLong as kAtomicLong -import kotlinx.atomicfu.AtomicRef as kAtomicRef -import kotlinx.atomicfu.update -import kotlinx.atomicfu.getAndUpdate - - -internal actual typealias AtomicLong = kAtomicLong -internal actual typealias AtomicReference = kAtomicRef - - -internal actual inline fun newAtomicLong(initial: Long): AtomicLong = - atomic(initial) - -internal actual inline fun newAtomicRef(initial: T): AtomicReference = - atomic(initial) - - -internal actual inline fun AtomicLong.get(): Long = - (this as kAtomicLong).value - -internal actual inline fun AtomicReference.get(): T = - (this as kAtomicRef).value - - -internal actual inline fun AtomicLong.update(operator: (Long) -> Long) = - (this as kAtomicLong).update(operator) - -internal actual inline fun AtomicReference.update(operator: (T) -> T) = - (this as kAtomicRef).update(operator) - -internal actual inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long = - (this as kAtomicLong).getAndUpdate(operator) - -internal actual inline fun AtomicReference.getAndUpdate(operator: (T) -> T): T = - (this as kAtomicRef).getAndUpdate(operator) - - -internal actual inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean = - (this as kAtomicLong).compareAndSet(expected, newValue) - -internal actual inline fun AtomicReference.compareAndSet(expected: T, newValue: T): Boolean = - (this as kAtomicRef).compareAndSet(expected, newValue) - - -private fun AtomicLong.compareAndExchange_impl(expected: Long, newValue: Long): Long { - val a = (this as kAtomicLong) - return Misc._compareAndExchange( - get = a::get, - cas = a::compareAndSet, - expected = expected, newValue = newValue - ) -} - - -private fun AtomicReference.compareAndExchange_impl(expected: T, newValue: T): T { - val a = (this as kAtomicRef) - return Misc._compareAndExchange( - get = a::get, - cas = a::compareAndSet, - expected = expected, newValue = newValue - ) -} - -internal actual inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long { - return this.compareAndExchange_impl(expected, newValue) -} - -internal actual inline fun AtomicReference.compareAndExchange(expected: T, newValue: T): T { - return this.compareAndExchange_impl(expected, newValue) -} \ No newline at end of file