5c5367d377
The following updates in the JVM/IR plugin were made: * Lots of refactoring with preparation for K/N support: commonization of transformations. * Improved error handling (checks for visibility constraints, appending message about usage constraints in case of an error). * Explicit requirements for the visibility of atomic properties: to prevent leaking they should be private/internal or be members of private/internal classes. * Fixed visibility of generated properties: volatile properties are always private and atomic updaters have the same visibility as the original atomic property. * Volatile fields are generated from scratch and original atomic properties are removed. * Delegated properties support is fixed (only declaration in the same scope is allowed). * Non-inline atomic extensions are forbidden. * For top-level atomics: only one wrapper class per file (with corresponding visibility) is generated. * Bug fixes. The corresponding tickets: https://github.com/Kotlin/kotlinx-atomicfu/issues/322 KT-60528 Merge-request: KT-MR-10579 Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
130 lines
3.4 KiB
Kotlin
Vendored
130 lines
3.4 KiB
Kotlin
Vendored
import kotlinx.atomicfu.*
|
|
import kotlin.test.*
|
|
|
|
class LoopTest {
|
|
private val a = atomic(0)
|
|
private val a1 = atomic(1)
|
|
private val b = atomic(true)
|
|
private val l = atomic(5000000000)
|
|
private val r = atomic<A>(A("aaaa"))
|
|
private val rs = atomic<String>("bbbb")
|
|
|
|
class A(val s: String)
|
|
|
|
fun atomicfuIntLoopTest() {
|
|
a.loop { value ->
|
|
if (a.compareAndSet(value, 777)) {
|
|
assertEquals(777, a.value)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
fun atomicfuBooleanLoopTest() {
|
|
b.loop { value ->
|
|
assertTrue(value)
|
|
if (!b.value) return
|
|
if (b.compareAndSet(value, false)) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
fun atomicfuLongLoopTest() {
|
|
l.loop { cur ->
|
|
if (l.compareAndSet(5000000003, 9000000000)) {
|
|
return
|
|
} else {
|
|
l.incrementAndGet()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun atomicfuRefLoopTest() {
|
|
r.loop { cur ->
|
|
assertEquals("aaaa", cur.s)
|
|
if (r.compareAndSet(cur, A("bbbb"))) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
fun atomicfuLoopTest() {
|
|
atomicfuIntLoopTest()
|
|
assertEquals(777, a.value)
|
|
atomicfuBooleanLoopTest()
|
|
assertFalse(b.value)
|
|
atomicfuLongLoopTest()
|
|
assertEquals(9000000000, l.value)
|
|
atomicfuRefLoopTest()
|
|
assertEquals("bbbb", r.value.s)
|
|
}
|
|
|
|
fun atomicfuUpdateTest() {
|
|
a.value = 0
|
|
a.update { value ->
|
|
val newValue = value + 1000
|
|
if (newValue >= 0) Int.MAX_VALUE else newValue
|
|
}
|
|
assertEquals(Int.MAX_VALUE, a.value)
|
|
b.update { true }
|
|
assertEquals(true, b.value)
|
|
assertTrue(b.value)
|
|
l.value = 0L
|
|
l.update { cur ->
|
|
val newValue = cur + 1000
|
|
if (newValue >= 0L) Long.MAX_VALUE else newValue
|
|
}
|
|
assertEquals(Long.MAX_VALUE, l.value)
|
|
r.lazySet(A("aaaa"))
|
|
r.update { cur ->
|
|
A("cccc${cur.s}")
|
|
}
|
|
assertEquals("ccccaaaa", r.value.s)
|
|
}
|
|
|
|
fun atomicfuUpdateAndGetTest() {
|
|
val res1 = a.updateAndGet { value ->
|
|
if (value >= 0) Int.MAX_VALUE else value
|
|
}
|
|
assertEquals(Int.MAX_VALUE, res1)
|
|
assertTrue(b.updateAndGet { true })
|
|
val res2 = l.updateAndGet { cur ->
|
|
if (cur >= 0L) Long.MAX_VALUE else cur
|
|
}
|
|
assertEquals(Long.MAX_VALUE, res2)
|
|
r.lazySet(A("aaaa"))
|
|
val res3 = r.updateAndGet { cur ->
|
|
A("cccc${cur.s}")
|
|
}
|
|
assertEquals("ccccaaaa", res3.s)
|
|
}
|
|
|
|
fun atomicfuGetAndUpdateTest() {
|
|
a.getAndUpdate { value ->
|
|
if (value >= 0) Int.MAX_VALUE else value
|
|
}
|
|
assertEquals(Int.MAX_VALUE, a.value)
|
|
b.getAndUpdate { true }
|
|
assertTrue(b.value)
|
|
l.getAndUpdate { cur ->
|
|
if (cur >= 0L) Long.MAX_VALUE else cur
|
|
}
|
|
assertEquals(Long.MAX_VALUE, l.value)
|
|
r.lazySet(A("aaaa"))
|
|
r.getAndUpdate { cur ->
|
|
A("cccc${cur.s}")
|
|
}
|
|
assertEquals("ccccaaaa", r.value.s)
|
|
}
|
|
}
|
|
|
|
fun box(): String {
|
|
val testClass = LoopTest()
|
|
testClass.atomicfuLoopTest()
|
|
testClass.atomicfuUpdateTest()
|
|
testClass.atomicfuUpdateAndGetTest()
|
|
testClass.atomicfuGetAndUpdateTest()
|
|
return "OK"
|
|
}
|