[atomicfu-K/N] Tests for K/N atomicfu-compiler-plugin
* `nativeTest` task now allows to provide compiler plugins that may be enabled during test compilation * test sets for JVM and K/N backends are equal KT-60800 describes all the issues with native tests that were solved in this commit. Co-authored-by: Dmitriy Dolovov <Dmitriy.Dolovov@jetbrains.com> Merge-request: KT-MR-11401 Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
This commit is contained in:
Vendored
+228
@@ -0,0 +1,228 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class AtomicIntArrayInlineExtensionTest {
|
||||
private val intArr = AtomicIntArray(10)
|
||||
private val a = atomic(0)
|
||||
|
||||
private inline fun casLoop(to: Int): Int {
|
||||
intArr[0].loop { cur ->
|
||||
if (intArr[0].compareAndSet(cur, to)) return intArr[0].value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Int): Int = intArr[3].loop { cur ->
|
||||
if (intArr[3].compareAndSet(cur, to)) return intArr[3].value
|
||||
return 777
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoop(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopExpression(to: Int): Int = loop { cur ->
|
||||
lazySet(cur + 10)
|
||||
return if (compareAndSet(cur, to)) value else incrementAndGet()
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopMixedReceivers(first: Int, second: Int, index: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
intArr[index].compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopRecursive(to: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, to)
|
||||
a.extensionLoop(5)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.foo(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return 777
|
||||
else return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.bar(delta: Int): Int {
|
||||
return foo(value + delta)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
assertEquals(5, casLoop(5))
|
||||
assertEquals(6, casLoopExpression(6))
|
||||
assertEquals(66, intArr[1].extensionLoop(66))
|
||||
assertEquals(66, intArr[2].extensionLoop(66))
|
||||
assertEquals(77, intArr[1].extensionLoopExpression(777))
|
||||
assertEquals(99, intArr[1].extensionLoopMixedReceivers(88, 99, 1))
|
||||
assertEquals(100, intArr[1].extensionLoopRecursive(100))
|
||||
assertEquals(777, intArr[1].bar(100))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicLongArrayInlineExtensionTest {
|
||||
private val longArr = AtomicLongArray(10)
|
||||
private val a = atomic(0L)
|
||||
|
||||
private inline fun casLoop(to: Long): Long {
|
||||
longArr[0].loop { cur ->
|
||||
if (longArr[0].compareAndSet(cur, to)) return longArr[0].value
|
||||
return 777L
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Long): Long = longArr[3].loop { cur ->
|
||||
if (longArr[3].compareAndSet(cur, to)) return longArr[3].value
|
||||
return 777L
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.extensionLoop(to: Long): Long {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
return 777L
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.extensionLoopExpression(to: Long): Long = loop { cur ->
|
||||
lazySet(cur + 10L)
|
||||
return if (compareAndSet(cur, to)) value else incrementAndGet()
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.extensionLoopMixedReceivers(first: Long, second: Long, index: Int): Long {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
longArr[index].compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.extensionLoopRecursive(to: Long): Long {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, to)
|
||||
a.extensionLoop(5L)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.foo(to: Long): Long {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return 777L
|
||||
else return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.bar(delta: Long): Long {
|
||||
return foo(value + delta)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
assertEquals(5L, casLoop(5L))
|
||||
assertEquals(6L, casLoopExpression(6L))
|
||||
assertEquals(66L, longArr[1].extensionLoop(66L))
|
||||
assertEquals(66L, longArr[2].extensionLoop(66L))
|
||||
assertEquals(77L, longArr[1].extensionLoopExpression(777L))
|
||||
assertEquals(99L, longArr[1].extensionLoopMixedReceivers(88L, 99L, 1))
|
||||
assertEquals(100L, longArr[1].extensionLoopRecursive(100L))
|
||||
assertEquals(777L, longArr[1].bar(100L))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicBooleanArrayInlineExtensionTest {
|
||||
private val booleanArr = AtomicBooleanArray(10)
|
||||
|
||||
private inline fun casLoop(to: Boolean): Boolean {
|
||||
booleanArr[0].loop { cur ->
|
||||
if (booleanArr[0].compareAndSet(cur, to)) return booleanArr[0].value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Boolean): Boolean = booleanArr[3].loop { cur ->
|
||||
if (booleanArr[3].compareAndSet(cur, to)) return booleanArr[3].value
|
||||
}
|
||||
|
||||
private inline fun AtomicBoolean.extensionLoop(to: Boolean): Boolean {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicBoolean.extensionLoopExpression(to: Boolean): Boolean = loop { cur ->
|
||||
lazySet(false)
|
||||
return if (compareAndSet(cur, to)) value else !value
|
||||
}
|
||||
|
||||
private inline fun AtomicBoolean.extensionLoopMixedReceivers(first: Boolean, second: Boolean, index: Int): Boolean {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
booleanArr[index].compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
assertEquals(true, casLoop(true))
|
||||
assertEquals(true, casLoopExpression(true))
|
||||
assertEquals(true, booleanArr[1].extensionLoop(true))
|
||||
assertEquals(true, booleanArr[1].extensionLoopExpression(true))
|
||||
assertEquals(false, booleanArr[7].extensionLoopMixedReceivers(true, false, 7))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicRefArrayInlineExtensionTest {
|
||||
private val refArr = atomicArrayOfNulls<String?>(10)
|
||||
private val a = atomic(0L)
|
||||
|
||||
private inline fun casLoop(to: String): String? {
|
||||
refArr[0].loop { cur ->
|
||||
if (refArr[0].compareAndSet(cur, to)) return refArr[0].value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: String): String? = refArr[3].loop { cur ->
|
||||
if (refArr[3].compareAndSet(cur, to)) return refArr[3].value
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String?>.extensionLoop(to: String): String? {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
else "incorrect"
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String?>.extensionLoopExpression(to: String): String? = loop { cur ->
|
||||
lazySet("aaa")
|
||||
return if (compareAndSet(cur, to)) value else "CAS_failed"
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String?>.extensionLoopMixedReceivers(first: String, second: String, index: Int): String? {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, first)
|
||||
refArr[index].compareAndSet(first, second)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
assertEquals("aaa", casLoop("aaa"))
|
||||
assertEquals("bbb", casLoopExpression("bbb"))
|
||||
assertEquals("ccc", refArr[1].extensionLoop("ccc"))
|
||||
assertEquals("CAS_failed", refArr[1].extensionLoopExpression("ccc"))
|
||||
assertEquals("bbb", refArr[7].extensionLoopMixedReceivers("aaa", "bbb", 7))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
AtomicIntArrayInlineExtensionTest().test()
|
||||
AtomicLongArrayInlineExtensionTest().test()
|
||||
AtomicBooleanArrayInlineExtensionTest().test()
|
||||
AtomicRefArrayInlineExtensionTest().test()
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class AtomicIntArrayAtomicfuInlineFunctionsTest {
|
||||
private val intArr = AtomicIntArray(10)
|
||||
|
||||
fun testSetArrayElementValueInLoop() {
|
||||
intArr[0].loop { cur ->
|
||||
assertTrue(intArr[0].compareAndSet(cur, 555))
|
||||
assertEquals(555, intArr[0].value)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun action(cur: Int): Int = cur * 1000
|
||||
|
||||
fun testArrayElementUpdate() {
|
||||
intArr[0].lazySet(5)
|
||||
intArr[0].update { cur -> action(cur) }
|
||||
assertEquals(intArr[0].value, 5000)
|
||||
}
|
||||
|
||||
fun testArrayElementGetAndUpdate() {
|
||||
intArr[0].lazySet(5)
|
||||
assertEquals(intArr[0].getAndUpdate{ cur -> action(cur) }, 5)
|
||||
assertEquals(intArr[0].value, 5000)
|
||||
}
|
||||
|
||||
fun testArrayElementUpdateAndGet() {
|
||||
intArr[0].lazySet(5)
|
||||
assertEquals(intArr[0].updateAndGet{ cur -> action(cur) }, 5000)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
testSetArrayElementValueInLoop()
|
||||
testArrayElementUpdate()
|
||||
testArrayElementGetAndUpdate()
|
||||
testArrayElementUpdateAndGet()
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicBooleanArrayAtomicfuInlineFunctionsTest {
|
||||
private val booleanArr = AtomicBooleanArray(10)
|
||||
|
||||
fun testSetArrayElementValueInLoop() {
|
||||
booleanArr[0].loop { cur ->
|
||||
assertTrue(booleanArr[0].compareAndSet(cur, true))
|
||||
assertEquals(true, booleanArr[0].value)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun action(cur: Boolean) = !cur
|
||||
|
||||
fun testArrayElementUpdate() {
|
||||
booleanArr[0].lazySet(true)
|
||||
booleanArr[0].update{ cur -> action(cur) }
|
||||
assertEquals(booleanArr[0].value, false)
|
||||
}
|
||||
|
||||
fun testArrayElementGetAndUpdate() {
|
||||
booleanArr[0].lazySet(true)
|
||||
assertEquals(booleanArr[0].getAndUpdate{ cur -> action(cur) }, true)
|
||||
assertEquals(booleanArr[0].value, false)
|
||||
}
|
||||
|
||||
fun testArrayElementUpdateAndGet() {
|
||||
booleanArr[0].lazySet(true)
|
||||
assertEquals(booleanArr[0].updateAndGet{ cur -> action(cur) }, false)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
testSetArrayElementValueInLoop()
|
||||
testArrayElementUpdate()
|
||||
testArrayElementGetAndUpdate()
|
||||
testArrayElementUpdateAndGet()
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicArrayAtomicfuInlineFunctionsTest {
|
||||
private val anyArr = atomicArrayOfNulls<Any?>(5)
|
||||
private val refArr = atomicArrayOfNulls<Box>(5)
|
||||
|
||||
private data class Box(val n: Int)
|
||||
|
||||
fun testSetArrayElementValueInLoop() {
|
||||
anyArr[0].loop { cur ->
|
||||
assertTrue(anyArr[0].compareAndSet(cur, IntArray(5)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun action(cur: Box?) = cur?.let { Box(cur.n * 10) }
|
||||
|
||||
fun testArrayElementUpdate() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
refArr[0].update { cur -> cur?.let { Box(cur.n * 10) } }
|
||||
assertEquals(refArr[0].value!!.n, 50)
|
||||
}
|
||||
|
||||
fun testArrayElementGetAndUpdate() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
assertEquals(refArr[0].getAndUpdate { cur -> action(cur) }!!.n, 5)
|
||||
assertEquals(refArr[0].value!!.n, 50)
|
||||
}
|
||||
|
||||
fun testArrayElementUpdateAndGet() {
|
||||
refArr[0].lazySet(Box(5))
|
||||
assertEquals(refArr[0].updateAndGet { cur -> action(cur) }!!.n, 50)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
testSetArrayElementValueInLoop()
|
||||
testArrayElementUpdate()
|
||||
testArrayElementGetAndUpdate()
|
||||
testArrayElementUpdateAndGet()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
AtomicIntArrayAtomicfuInlineFunctionsTest().test()
|
||||
AtomicBooleanArrayAtomicfuInlineFunctionsTest().test()
|
||||
AtomicArrayAtomicfuInlineFunctionsTest().test()
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
private val topLevelA = atomic(0)
|
||||
|
||||
class ComplexLoopTest {
|
||||
private val a = atomic(10)
|
||||
private val long = atomic(6757L)
|
||||
private val b = atomic(11)
|
||||
private val c = atomic(12)
|
||||
private val r = atomic<String>("aaa")
|
||||
private val intArr = AtomicIntArray(10)
|
||||
|
||||
private inline fun AtomicInt.fooInt() {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, 67)) return
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.fooLong() {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, 67L)) return
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun embeddedLoops(to: Int): Int =
|
||||
a.loop { aValue ->
|
||||
if (!a.compareAndSet(aValue, to)) return 666
|
||||
b.loop { bValue ->
|
||||
return if (b.compareAndSet(bValue, to)) a.value + b.value else 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionEmbeddedLoops(to: Int): Int =
|
||||
loop { cur1 ->
|
||||
compareAndSet(cur1, to)
|
||||
loop { cur2 ->
|
||||
return cur2
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun embeddedUpdate(to: Int): Int =
|
||||
a.loop { aValue ->
|
||||
a.compareAndSet(aValue, to)
|
||||
return a.updateAndGet { cur -> cur + 100 }
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String>.extesntionEmbeddedRefUpdate(to: String): String =
|
||||
loop { value ->
|
||||
compareAndSet(value, to)
|
||||
return updateAndGet { cur -> "${cur}AAA" }
|
||||
}
|
||||
|
||||
fun test() {
|
||||
a.fooInt()
|
||||
assertEquals(67, a.value)
|
||||
b.fooInt()
|
||||
assertEquals(67, b.value)
|
||||
c.fooInt()
|
||||
assertEquals(67, c.value)
|
||||
long.fooLong()
|
||||
assertEquals(67L, long.value)
|
||||
assertEquals(24, embeddedLoops(12))
|
||||
assertEquals(77, c.extensionEmbeddedLoops(77))
|
||||
assertEquals(66, intArr[0].extensionEmbeddedLoops(66))
|
||||
assertEquals(166, embeddedUpdate(66))
|
||||
assertEquals("bbbAAA", r.extesntionEmbeddedRefUpdate("bbb"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testComplexLoopTest() {
|
||||
val testClass = ComplexLoopTest()
|
||||
testClass.test()
|
||||
}
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ExtensionLoopTest {
|
||||
private val a = atomic(0)
|
||||
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)
|
||||
|
||||
private inline fun casLoop(to: Int): Int {
|
||||
a.loop { cur ->
|
||||
if (a.compareAndSet(cur, to)) return a.value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun casLoopExpression(to: Int): Int = a.loop { cur ->
|
||||
if (a.compareAndSet(cur, to)) return a.value
|
||||
return 777
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoop(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return value
|
||||
return 777
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopExpression(to: Int): Int = loop { cur ->
|
||||
lazySet(cur + 10)
|
||||
return if (compareAndSet(cur, to)) value + 1 else incrementAndGet()
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionLoopRecursive(to: Int): Int {
|
||||
loop { cur ->
|
||||
compareAndSet(cur, to)
|
||||
extensionLoop(5)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.foo(to: Int): Int {
|
||||
loop { cur ->
|
||||
if (compareAndSet(cur, to)) return 777
|
||||
else return value
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.bar(delta: Int): Int {
|
||||
return foo(value + delta)
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.extensionEmbeddedLoops(to: Int): Int =
|
||||
loop { cur1 ->
|
||||
compareAndSet(value, to)
|
||||
loop { cur2 ->
|
||||
return cur2
|
||||
}
|
||||
}
|
||||
|
||||
fun testIntExtensionLoops() {
|
||||
assertEquals(5, casLoop(5))
|
||||
assertEquals(45, a.extensionEmbeddedLoops(45))
|
||||
assertEquals(6, casLoopExpression(6))
|
||||
assertEquals(17, a.extensionLoopExpression(777))
|
||||
assertEquals(66, a.extensionLoop(66))
|
||||
assertEquals(5, a.extensionLoopRecursive(100))
|
||||
assertEquals(777, a.bar(100))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val ref = atomic<String>("aaa")
|
||||
|
||||
private inline fun AtomicRef<String>.topLevelExtensionLoop(to: String): String = loop { cur ->
|
||||
lazySet(cur + to)
|
||||
return value
|
||||
}
|
||||
|
||||
fun testTopLevelExtensionLoop() {
|
||||
assertEquals("aaattt", ref.topLevelExtensionLoop("ttt"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExtensionLoop() {
|
||||
val testClass = ExtensionLoopTest()
|
||||
testClass.testIntExtensionLoops()
|
||||
testTopLevelExtensionLoop()
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ExtensionsTest {
|
||||
private val a = atomic(0)
|
||||
private val l = atomic(0L)
|
||||
private val s = atomic<String?>(null)
|
||||
private val b = atomic(true)
|
||||
|
||||
fun testScopedFieldGetters() {
|
||||
check(a.value == 0)
|
||||
val update = 3
|
||||
a.lazySet(update)
|
||||
check(a.compareAndSet(update, 8))
|
||||
a.lazySet(1)
|
||||
check(a.value == 1)
|
||||
check(a.getAndSet(2) == 1)
|
||||
check(a.value == 2)
|
||||
check(a.getAndIncrement() == 2)
|
||||
check(a.value == 3)
|
||||
check(a.getAndDecrement() == 3)
|
||||
check(a.value == 2)
|
||||
check(a.getAndAdd(2) == 2)
|
||||
check(a.value == 4)
|
||||
check(a.addAndGet(3) == 7)
|
||||
check(a.value == 7)
|
||||
check(a.incrementAndGet() == 8)
|
||||
check(a.value == 8)
|
||||
check(a.decrementAndGet() == 7)
|
||||
check(a.value == 7)
|
||||
check(a.compareAndSet(7, 10))
|
||||
}
|
||||
|
||||
private inline fun AtomicInt.intExtensionArithmetic() {
|
||||
value = 0
|
||||
check(value == 0)
|
||||
val update = 3
|
||||
lazySet(update)
|
||||
check(compareAndSet(update, 8))
|
||||
lazySet(1)
|
||||
check(value == 1)
|
||||
check(getAndSet(2) == 1)
|
||||
check(value == 2)
|
||||
check(getAndIncrement() == 2)
|
||||
check(value == 3)
|
||||
check(getAndDecrement() == 3)
|
||||
check(value == 2)
|
||||
check(getAndAdd(2) == 2)
|
||||
check(value == 4)
|
||||
check(addAndGet(3) == 7)
|
||||
check(value == 7)
|
||||
check(incrementAndGet() == 8)
|
||||
check(value == 8)
|
||||
check(decrementAndGet() == 7)
|
||||
check(value == 7)
|
||||
check(compareAndSet(7, 10))
|
||||
check(compareAndSet(value, 55))
|
||||
check(value == 55)
|
||||
}
|
||||
|
||||
private inline fun AtomicLong.longExtensionArithmetic() {
|
||||
value = 2424920024888888848
|
||||
check(value == 2424920024888888848)
|
||||
lazySet(8424920024888888848)
|
||||
check(value == 8424920024888888848)
|
||||
check(getAndSet(8924920024888888848) == 8424920024888888848)
|
||||
check(value == 8924920024888888848)
|
||||
check(incrementAndGet() == 8924920024888888849) // fails
|
||||
check(value == 8924920024888888849)
|
||||
check(getAndDecrement() == 8924920024888888849)
|
||||
check(value == 8924920024888888848)
|
||||
check(getAndAdd(100000000000000000) == 8924920024888888848)
|
||||
check(value == 9024920024888888848)
|
||||
check(addAndGet(-9223372036854775807) == -198452011965886959)
|
||||
check(value == -198452011965886959)
|
||||
check(incrementAndGet() == -198452011965886958)
|
||||
check(value == -198452011965886958)
|
||||
check(decrementAndGet() == -198452011965886959)
|
||||
check(value == -198452011965886959)
|
||||
}
|
||||
|
||||
private inline fun AtomicRef<String?>.refExtension() {
|
||||
value = "aaa"
|
||||
check(value == "aaa")
|
||||
lazySet("bb")
|
||||
check(value == "bb")
|
||||
check(getAndSet("ccc") == "bb")
|
||||
check(value == "ccc")
|
||||
}
|
||||
|
||||
private inline fun AtomicBoolean.booleanExtensionArithmetic() {
|
||||
value = false
|
||||
check(!value)
|
||||
lazySet(true)
|
||||
check(value)
|
||||
check(getAndSet(true))
|
||||
check(compareAndSet(value, false))
|
||||
check(!value)
|
||||
}
|
||||
|
||||
fun testExtension() {
|
||||
a.intExtensionArithmetic()
|
||||
l.longExtensionArithmetic()
|
||||
s.refExtension()
|
||||
b.booleanExtensionArithmetic()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
val testClass = ExtensionsTest()
|
||||
testClass.testScopedFieldGetters()
|
||||
testClass.testExtension()
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class InlineExtensionWithTypeParameterTest {
|
||||
abstract class Segment<S : Segment<S>>(val id: Int)
|
||||
class SemaphoreSegment(id: Int) : Segment<SemaphoreSegment>(id)
|
||||
|
||||
private inline fun <S : Segment<S>> AtomicRef<S>.foo(
|
||||
id: Int,
|
||||
startFrom: S
|
||||
): Int {
|
||||
lazySet(startFrom)
|
||||
return value.getSegmentId()
|
||||
}
|
||||
|
||||
private inline fun <S : Segment<S>> S.getSegmentId(): Int {
|
||||
var cur: S = this
|
||||
return cur.id
|
||||
}
|
||||
|
||||
private val sref = atomic(SemaphoreSegment(0))
|
||||
|
||||
fun testInlineExtensionWithTypeParameter() {
|
||||
val s = SemaphoreSegment(77)
|
||||
assertEquals(77, sref.foo(0, s))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
val testClass = InlineExtensionWithTypeParameterTest()
|
||||
testClass.testInlineExtensionWithTypeParameter()
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LambdaTest {
|
||||
private val a = atomic(0)
|
||||
private val rs = atomic<String>("bbbb")
|
||||
|
||||
private inline fun <T> inlineLambda(
|
||||
arg: T,
|
||||
crossinline block: (T) -> Unit
|
||||
) = block(arg)
|
||||
|
||||
fun loopInLambda1(to: Int) = inlineLambda(to) sc@ { arg ->
|
||||
a.loop { value ->
|
||||
a.compareAndSet(value, arg)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
|
||||
fun loopInLambda2(to: Int) = inlineLambda(to) { arg1 ->
|
||||
inlineLambda(arg1) sc@ { arg2 ->
|
||||
a.loop { value ->
|
||||
a.compareAndSet(value, arg2)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loopInLambda2Ref(to: String) = inlineLambda(to) { arg1 ->
|
||||
inlineLambda(arg1) sc@ { arg2 ->
|
||||
rs.loop { value ->
|
||||
rs.compareAndSet(value, arg2)
|
||||
return@sc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
loopInLambda1(34)
|
||||
assertEquals(34, a.value)
|
||||
loopInLambda1(77)
|
||||
assertEquals(77, a.value)
|
||||
loopInLambda2Ref("bbb")
|
||||
assertEquals("bbb", rs.value)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
val testClass = LambdaTest()
|
||||
testClass.test()
|
||||
}
|
||||
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LockFreeIntBitsTest {
|
||||
fun testBasic() {
|
||||
val bs = LockFreeIntBits()
|
||||
assertTrue(!bs[0])
|
||||
assertTrue(bs.bitSet(0))
|
||||
assertTrue(bs[0])
|
||||
assertTrue(!bs.bitSet(0))
|
||||
|
||||
assertTrue(!bs[1])
|
||||
assertTrue(bs.bitSet(1))
|
||||
assertTrue(bs[1])
|
||||
assertTrue(!bs.bitSet(1))
|
||||
assertTrue(!bs.bitSet(0))
|
||||
|
||||
assertTrue(bs[0])
|
||||
assertTrue(bs.bitClear(0))
|
||||
assertTrue(!bs.bitClear(0))
|
||||
|
||||
assertTrue(bs[1])
|
||||
}
|
||||
}
|
||||
|
||||
class LockFreeIntBits {
|
||||
private val bits = atomic(0)
|
||||
|
||||
private fun Int.mask() = 1 shl this
|
||||
|
||||
operator fun get(index: Int): Boolean = bits.value and index.mask() != 0
|
||||
|
||||
// User-defined private inline function
|
||||
private inline fun bitUpdate(check: (Int) -> Boolean, upd: (Int) -> Int): Boolean {
|
||||
bits.update {
|
||||
if (check(it)) return false
|
||||
upd(it)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun bitSet(index: Int): Boolean {
|
||||
val mask = index.mask()
|
||||
return bitUpdate({ it and mask != 0 }, { it or mask })
|
||||
}
|
||||
|
||||
fun bitClear(index: Int): Boolean {
|
||||
val mask = index.mask()
|
||||
return bitUpdate({ it and mask == 0 }, { it and mask.inv() })
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
val testClass = LockFreeIntBitsTest()
|
||||
testClass.testBasic()
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LockTest {
|
||||
private val inProgressLock = atomic(false)
|
||||
|
||||
fun testLock() {
|
||||
var result = ""
|
||||
if (inProgressLock.tryAcquire()) {
|
||||
result = "OK"
|
||||
}
|
||||
assertEquals("OK", result)
|
||||
}
|
||||
}
|
||||
|
||||
// This function will be removed by transformer
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true)
|
||||
|
||||
// This function is here to test if the Kotlin metadata still consistent after transform
|
||||
// It is used in ReflectionTest, DO NOT REMOVE
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun <AA, BB : Number> String.reflectionTest(mapParam: Map<in AA, BB>): List<BB> = error("no impl")
|
||||
|
||||
@Test
|
||||
fun box() {
|
||||
val testClass = LockTest()
|
||||
testClass.testLock()
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import kotlinx.atomicfu.*
|
||||
import kotlin.test.*
|
||||
|
||||
class ParameterizedInlineFunExtensionTest {
|
||||
|
||||
private inline fun <S> AtomicRef<S>.foo(res1: S, res2: S, foo: (S) -> S): S {
|
||||
val res = bar(res1, res2)
|
||||
return res
|
||||
}
|
||||
|
||||
private inline fun <S> AtomicRef<S>.bar(res1: S, res2: S): S {
|
||||
return res2
|
||||
}
|
||||
|
||||
private val tail = atomic("aaa")
|
||||
|
||||
fun testClose() {
|
||||
assertEquals("bbb", tail.bar("aaa", "bbb"))
|
||||
val res = tail.foo("bbb", "ccc") { s -> s }
|
||||
assertEquals("ccc", res)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testParameterizedInlineFunExtensionTest() {
|
||||
val testClass = ParameterizedInlineFunExtensionTest()
|
||||
testClass.testClose()
|
||||
}
|
||||
Reference in New Issue
Block a user