Removed excess atomic functions and minor fixes

This commit is contained in:
Andrew Golovashevich 2025-08-24 03:59:16 +03:00
parent 999ff63ccf
commit 7131a38bd4
9 changed files with 53 additions and 255 deletions

View File

@ -0,0 +1,5 @@
package ru.landgrafhomyak.utility.closeable_state_1
internal object _MiscMultiplatform {
internal const val CLOSED_STATE_VALUE = -0x4000_0000_0000_0000L
}

View File

@ -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<T>
internal expect inline fun newAtomicLong(initial: Long): AtomicLong
internal expect inline fun <T> newAtomicRef(initial: T): AtomicReference<T>
internal expect inline fun AtomicLong.get(): Long
internal expect inline fun <T> AtomicReference<T>.get(): T
internal expect inline fun AtomicLong.update(operator: (Long) -> Long)
internal expect inline fun <T> AtomicReference<T>.update(operator: (T) -> T)
internal expect inline fun AtomicLong.getAndUpdate(operator: (Long) -> Long): Long
internal expect inline fun <T> AtomicReference<T>.getAndUpdate(operator: (T) -> T): T
internal expect inline fun AtomicLong.compareAndSet(expected: Long, newValue: Long): Boolean
internal expect inline fun <T> AtomicReference<T>.compareAndSet(expected: T, newValue: T): Boolean
internal expect inline fun AtomicLong.compareAndExchange(expected: Long, newValue: Long): Long
internal expect inline fun <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T

View File

@ -13,7 +13,7 @@ public /* open */ class jErrorOnConcurrentAccessState
private final AtomicReference<State> _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 "<closeable error-on-concurrent-access state [in use]>";
case OPEN:
return "<closeable error-on-concurrent-access state [close]>";
return "<closeable error-on-concurrent-access state [closed]>";
}
throw new RuntimeException("Unreachable");
}

View File

@ -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;
}

View File

@ -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<T> = jAtomicReference<T>
internal actual inline fun newAtomicLong(initial: Long): AtomicLong =
jAtomicLong(initial)
internal actual inline fun <T> newAtomicRef(initial: T): AtomicReference<T> =
jAtomicReference(initial)
internal actual inline fun AtomicLong.get(): Long =
(this as jAtomicLong).get()
internal actual inline fun <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.`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 <T> AtomicReference<T>.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<Nothing?>()
try {
a.compareAndExchange(null, null)
return@run true
} catch (_: NoSuchMethodError) {
return@run false
}
}

View File

@ -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 -> "<closeable error-on-concurrent-access state [free]>"
State.IN_USE -> "<closeable error-on-concurrent-access state [in use]>"
State.CLOSED -> "<closeable error-on-concurrent-access state [close]>"
State.CLOSED -> "<closeable error-on-concurrent-access state [closed]>"
}
}

View File

@ -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 "<closeable usages counter [closed]>"

View File

@ -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 <T> AtomicRef<T>.compareAndExchange(expected: T, newValue: T): T {
return this.getAndUpdate { old ->
if (old != expected) return@compareAndExchange old
return@getAndUpdate newValue
}
}
}

View File

@ -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<T> = kAtomicRef<T>
internal actual inline fun newAtomicLong(initial: Long): AtomicLong =
atomic(initial)
internal actual inline fun <T> newAtomicRef(initial: T): AtomicReference<T> =
atomic(initial)
internal actual inline fun AtomicLong.get(): Long =
(this as kAtomicLong).value
internal actual inline fun <T> AtomicReference<T>.get(): T =
(this as kAtomicRef).value
internal actual inline fun AtomicLong.update(operator: (Long) -> Long) =
(this as kAtomicLong).update(operator)
internal actual inline fun <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.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 <T> AtomicReference<T>.compareAndExchange(expected: T, newValue: T): T {
return this.compareAndExchange_impl(expected, newValue)
}