[K/N] Migrate runtime/atomics tests to new testing infra ^KT-61259
This commit is contained in:
committed by
Space Team
parent
ba374bb45c
commit
2f22b0a6b0
@@ -1008,33 +1008,6 @@ standaloneTest("freeze_disabled") {
|
||||
testLogger = KonanTest.Logger.SILENT
|
||||
}
|
||||
|
||||
tasks.register("atomicSmokeTest", KonanLocalTest) {
|
||||
source = "runtime/atomics/atomic_smoke.kt"
|
||||
}
|
||||
|
||||
tasks.register("atomicStressTest", KonanLocalTest) {
|
||||
source = "runtime/atomics/atomic_stress.kt"
|
||||
}
|
||||
|
||||
tasks.register("atomic0", KonanLocalTest) {
|
||||
useGoldenData = true
|
||||
source = "runtime/atomics/atomic0.kt"
|
||||
}
|
||||
|
||||
standaloneTest("atomic1") {
|
||||
// Note: This test reproduces a race, so it'll start flaking if problem is reintroduced.
|
||||
enabled = false // Needs USE_CYCLIC_GC, which is disabled.
|
||||
source = "runtime/atomics/atomic1.kt"
|
||||
}
|
||||
|
||||
tasks.register("atomicArraySmokeTest", KonanLocalTest) {
|
||||
source = "runtime/atomics/atomic_array_smoke.kt"
|
||||
}
|
||||
|
||||
tasks.register("atomicArrayStressTest", KonanLocalTest) {
|
||||
source = "runtime/atomics/atomic_array_stress.kt"
|
||||
}
|
||||
|
||||
tasks.register("lazy0", KonanLocalTest) {
|
||||
useGoldenData = true
|
||||
source = "runtime/workers/lazy0.kt"
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, FreezingIsDeprecated::class, ObsoleteWorkersApi::class)
|
||||
package runtime.atomics.atomic0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.concurrent.AtomicLong
|
||||
import kotlin.concurrent.AtomicReference
|
||||
|
||||
fun test1(workers: Array<Worker>) {
|
||||
val atomic = AtomicInt(15)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { atomic }) {
|
||||
input -> input.addAndGet(1)
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
println(atomic.value)
|
||||
}
|
||||
|
||||
fun test2(workers: Array<Worker>) {
|
||||
val atomic = AtomicInt(1)
|
||||
val counter = AtomicInt(0)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { Triple(atomic, workerIndex, counter) }) {
|
||||
(place, index, result) ->
|
||||
// Here we simulate mutex using [place] location to store tag of the current worker.
|
||||
// When it is negative - worker executes exclusively.
|
||||
val tag = index + 1
|
||||
while (place.compareAndExchange(tag, -tag) != tag) {}
|
||||
val ok1 = result.addAndGet(1) == index + 1
|
||||
// Now, let the next worker run.
|
||||
val ok2 = place.compareAndExchange(-tag, tag + 1) == -tag
|
||||
ok1 && ok2
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
assertEquals(it.result, true)
|
||||
}
|
||||
println(counter.value)
|
||||
}
|
||||
|
||||
data class Data(val value: Int)
|
||||
|
||||
fun test3(workers: Array<Worker>) {
|
||||
val common = AtomicReference<Data?>(null)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { Pair(common, workerIndex) }) {
|
||||
(place, index) ->
|
||||
val mine = Data(index).freeze()
|
||||
// Try to publish our own data, until successful, in a tight loop.
|
||||
while (!place.compareAndSet(null, mine)) {}
|
||||
}
|
||||
})
|
||||
val seen = mutableSetOf<Data>()
|
||||
for (i in 0 until workers.size) {
|
||||
do {
|
||||
val current = common.value
|
||||
if (current != null && !seen.contains(current)) {
|
||||
seen += current
|
||||
// Let others publish.
|
||||
assertEquals(common.compareAndExchange(current, null), current)
|
||||
break
|
||||
}
|
||||
} while (true)
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(seen.size, workers.size)
|
||||
}
|
||||
|
||||
fun test4LegacyMM() {
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
AtomicReference(Data(1))
|
||||
}
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
AtomicReference<Data?>(null).compareAndExchange(null, Data(2))
|
||||
}
|
||||
}
|
||||
|
||||
fun test4() {
|
||||
run {
|
||||
val ref = AtomicReference(Data(1))
|
||||
assertEquals(1, ref.value.value)
|
||||
}
|
||||
run {
|
||||
val ref = AtomicReference<Data?>(null)
|
||||
ref.compareAndExchange(null, Data(2))
|
||||
assertEquals(2, ref.value!!.value)
|
||||
}
|
||||
if (Platform.isFreezingEnabled) {
|
||||
run {
|
||||
val ref = AtomicReference<Data?>(null).freeze()
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
ref.compareAndExchange(null, Data(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test5LegacyMM() {
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
AtomicReference<Data?>(null).value = Data(2)
|
||||
}
|
||||
val ref = AtomicReference<Data?>(null)
|
||||
val value = Data(3).freeze()
|
||||
assertEquals(null, ref.value)
|
||||
ref.value = value
|
||||
assertEquals(3, ref.value!!.value)
|
||||
}
|
||||
|
||||
fun test5() {
|
||||
val ref = AtomicReference<Data?>(null)
|
||||
ref.value = Data(2)
|
||||
assertEquals(2, ref.value!!.value)
|
||||
ref.value = Data(3).freeze()
|
||||
assertEquals(3, ref.value!!.value)
|
||||
}
|
||||
|
||||
fun test6() {
|
||||
val int = AtomicInt(0)
|
||||
int.value = 239
|
||||
assertEquals(239, int.value)
|
||||
val long = AtomicLong(0)
|
||||
long.value = 239L
|
||||
assertEquals(239L, long.value)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
fun test7() {
|
||||
val ref = AtomicReference(Array(1) { "hey" })
|
||||
ref.value[0] = "ho"
|
||||
assertEquals(ref.value[0], "ho")
|
||||
ref.value = Array(1) { "po" }
|
||||
assertEquals(ref.value[0], "po")
|
||||
ref.freeze()
|
||||
if (Platform.isFreezingEnabled) {
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
ref.value = Array(1) { "no" }
|
||||
}
|
||||
assertFailsWith<InvalidMutabilityException> {
|
||||
ref.value[0] = "go"
|
||||
}
|
||||
}
|
||||
ref.value = Array(1) { "so" }.freeze()
|
||||
assertEquals(ref.value[0], "so")
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
val COUNT = 20
|
||||
val workers = Array(COUNT, { _ -> Worker.start()})
|
||||
|
||||
test1(workers)
|
||||
test2(workers)
|
||||
test3(workers)
|
||||
if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) {
|
||||
test4()
|
||||
test5()
|
||||
} else {
|
||||
test4LegacyMM()
|
||||
test5LegacyMM()
|
||||
}
|
||||
test6()
|
||||
test7()
|
||||
|
||||
workers.forEach {
|
||||
it.requestTermination().result
|
||||
}
|
||||
println("OK")
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
35
|
||||
20
|
||||
OK
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// Note: This test reproduces a race, so it'll start flaking if problem is reintroduced.
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.internal.*
|
||||
import kotlin.native.runtime.GC
|
||||
|
||||
val thrashGC = AtomicInt(1)
|
||||
val canStartCreating = AtomicInt(0)
|
||||
val createdCount = AtomicInt(0)
|
||||
val canStartReading = AtomicInt(0)
|
||||
const val atomicsCount = 1000
|
||||
const val workersCount = 10
|
||||
|
||||
fun main() {
|
||||
val gcWorker = Worker.start()
|
||||
val future = gcWorker.execute(TransferMode.SAFE, {}, {
|
||||
canStartCreating.value = 1
|
||||
while (thrashGC.value != 0) {
|
||||
GC.collectCyclic()
|
||||
}
|
||||
GC.collect()
|
||||
})
|
||||
|
||||
while (canStartCreating.value == 0) {}
|
||||
|
||||
val workers = Array(workersCount) { Worker.start() }
|
||||
val futures = workers.map {
|
||||
it.execute(TransferMode.SAFE, {}, {
|
||||
val atomics = Array(atomicsCount) {
|
||||
AtomicReference<Any?>(Any().freeze())
|
||||
}
|
||||
createdCount.incrementAndGet()
|
||||
while (canStartReading.value == 0) {}
|
||||
GC.collect()
|
||||
atomics.all { it.value != null }
|
||||
})
|
||||
}
|
||||
|
||||
while (createdCount.value != workersCount) {}
|
||||
|
||||
thrashGC.value = 0
|
||||
future.result
|
||||
GC.collect()
|
||||
canStartReading.value = 1
|
||||
|
||||
assertTrue(futures.all { it.result })
|
||||
|
||||
for (worker in workers) {
|
||||
worker.requestTermination().result
|
||||
}
|
||||
gcWorker.requestTermination().result
|
||||
}
|
||||
@@ -1,596 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||
|
||||
package runtime.atomics.atomic_array_smoke
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.concurrent.*
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayConstructor() {
|
||||
val arr1 = AtomicIntArray(6)
|
||||
assertEquals(arr1[4], 0)
|
||||
assertEquals(arr1.length, 6)
|
||||
|
||||
val arr2 = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(arr2[4], 40)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicIntArray(0)
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicIntArray(-5)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayGetElement() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
assertEquals(i * 10, atomicIntArr[i], "testAtomicIntArrayGetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr[22]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArraySetElement() {
|
||||
val atomicIntArr = AtomicIntArray(10)
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
atomicIntArr[i] = i * 10
|
||||
}
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
assertEquals(i * 10, atomicIntArr[i], "testAtomicIntArraySetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicIntArr[22] = 100
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicIntArr[-1] = 100
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayCompareAndExchange() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
val res1 = atomicIntArr.compareAndExchange(2, 20, 222) // success
|
||||
assertTrue(res1 == 20 && atomicIntArr[2] == 222, "testAtomicIntArrayCompareAndExchange: FAIL 1")
|
||||
val res2 = atomicIntArr.compareAndExchange(2, 222, 2222) // success
|
||||
assertTrue(res2 == 222 && atomicIntArr[2] == 2222, "testAtomicIntArrayCompareAndExchange: FAIL 2")
|
||||
val res3 = atomicIntArr.compareAndExchange(2, 223, 22222) // should fail
|
||||
assertTrue(res3 == 2222 && atomicIntArr[2] == 2222, "testAtomicIntArrayCompareAndExchange: FAIL 3")
|
||||
val res4 = atomicIntArr.compareAndExchange(9, 10, 999) // should fail
|
||||
assertTrue(res4 == 90 && atomicIntArr[9] == 90, "testAtomicIntArrayCompareAndExchange: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndExchange(10, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndExchange(-1, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayCompareAndSet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
val res1 = atomicIntArr.compareAndSet(2, 20, 222) // success
|
||||
assertTrue(res1 && atomicIntArr[2] == 222, "testAtomicIntArrayCompareAndSet: FAIL 1")
|
||||
val res2 = atomicIntArr.compareAndSet(2, 222, 2222) // success
|
||||
assertTrue(res2 && atomicIntArr[2] == 2222, "testAtomicIntArrayCompareAndSet: FAIL 2")
|
||||
val res3 = atomicIntArr.compareAndSet(2, 223, 22222) // should fail
|
||||
assertTrue(!res3 && atomicIntArr[2] == 2222, "testAtomicIntArrayCompareAndSet: FAIL 3")
|
||||
val res4 = atomicIntArr.compareAndSet(9, 10, 999) // should fail
|
||||
assertTrue(!res4 && atomicIntArr[9] == 90, "testAtomicIntArrayCompareAndSet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndSet(10, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndSet(-1, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayGetAndSet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(20, atomicIntArr.getAndSet(2, 200), "testAtomicIntArrayGetAndSet: FAIL 1")
|
||||
assertEquals(200, atomicIntArr.getAndSet(2, 2000), "testAtomicIntArrayGetAndSet: FAIL 2")
|
||||
assertEquals(2000, atomicIntArr[2], "testAtomicIntArrayGetAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndSet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndSet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayGetAndAdd() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndAdd(1, 100), "testAtomicIntArrayGetAndAdd: FAIL 1")
|
||||
assertEquals(110, atomicIntArr[1], "testAtomicIntArrayGetAndAdd: FAIL 2")
|
||||
assertEquals(110, atomicIntArr.getAndAdd(1, -100), "testAtomicIntArrayGetAndAdd: FAIL 3")
|
||||
assertEquals(10, atomicIntArr[1], "testAtomicIntArrayGetAndAdd: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndAdd(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndAdd(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayAddAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(110, atomicIntArr.addAndGet(1, 100), "testAtomicIntArrayAddAndGet: FAIL 1")
|
||||
assertEquals(110, atomicIntArr[1], "testAtomicIntArrayAddAndGet: FAIL 2")
|
||||
assertEquals(10, atomicIntArr.addAndGet(1, -100), "testAtomicIntArrayAddAndGet: FAIL 3")
|
||||
assertEquals(10, atomicIntArr[1], "testAtomicIntArrayAddAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.addAndGet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayGetAndIncrement() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndIncrement(1), "testAtomicIntArrayGetAndIncrement: FAIL 1")
|
||||
assertEquals(11, atomicIntArr[1], "testAtomicIntArrayGetAndIncrement: FAIL 2")
|
||||
assertEquals(11, atomicIntArr.getAndIncrement(1), "testAtomicIntArrayGetAndIncrement: FAIL 3")
|
||||
assertEquals(12, atomicIntArr[1], "testAtomicIntArrayGetAndIncrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndIncrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndIncrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayIncrementAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(11, atomicIntArr.incrementAndGet(1), "testAtomicIntArrayIncrementAndGet: FAIL 1")
|
||||
assertEquals(11, atomicIntArr[1], "testAtomicIntArrayIncrementAndGet: FAIL 2")
|
||||
assertEquals(12, atomicIntArr.incrementAndGet(1), "testAtomicIntArrayIncrementAndGet: FAIL 3")
|
||||
assertEquals(12, atomicIntArr[1], "testAtomicIntArrayIncrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.incrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.incrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayGetAndDecrement() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndDecrement(1), "testAtomicIntArrayGetAndDecrement: FAIL 1")
|
||||
assertEquals(9, atomicIntArr[1], "testAtomicIntArrayGetAndDecrement: FAIL 2")
|
||||
assertEquals(9, atomicIntArr.getAndDecrement(1), "testAtomicIntArrayGetAndDecrement: FAIL 3")
|
||||
assertEquals(8, atomicIntArr[1], "testAtomicIntArrayGetAndDecrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndDecrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndDecrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicIntArrayDecrementAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(9, atomicIntArr.decrementAndGet(1), "testAtomicIntArrayDecrementAndGet: FAIL 1")
|
||||
assertEquals(9, atomicIntArr[1], "testAtomicIntArrayDecrementAndGet: FAIL 2")
|
||||
assertEquals(8, atomicIntArr.decrementAndGet(1), "testAtomicIntArrayDecrementAndGet: FAIL 3")
|
||||
assertEquals(8, atomicIntArr[1], "testAtomicIntArrayDecrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.decrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.decrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayConstructor() {
|
||||
val arr1 = AtomicLongArray(6)
|
||||
assertEquals(arr1[4], 0L)
|
||||
assertEquals(arr1.length, 6)
|
||||
val arr2 = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(arr2[4], 40L)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicLongArray(0)
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicLongArray(-5)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayGetElement() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
assertEquals(i * 10L, atomicLongArr[i], "testAtomicLongArrayGetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr[22]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArraySetElement() {
|
||||
val atomicLongArr = AtomicLongArray(10)
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
atomicLongArr[i] = i * 10L
|
||||
}
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
assertEquals(i * 10L, atomicLongArr[i], "testAtomicLongArraySetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr[10] = 3998009
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr[-1] = 3998009
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayCompareAndExchange() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
val res1 = atomicLongArr.compareAndExchange(2, 20L, 222L) // success
|
||||
assertTrue(res1 == 20L && atomicLongArr[2] == 222L, "testAtomicLongArrayCompareAndExchange: FAIL 1")
|
||||
val res2 = atomicLongArr.compareAndExchange(2, 222L, 2222L) // success
|
||||
assertTrue(res2 == 222L && atomicLongArr[2] == 2222L, "testAtomicLongArrayCompareAndExchange: FAIL 2")
|
||||
val res3 = atomicLongArr.compareAndExchange(2, 223L, 22222L) // should fail
|
||||
assertTrue(res3 == 2222L && atomicLongArr[2] == 2222L, "testAtomicLongArrayCompareAndExchange: FAIL 3")
|
||||
val res4 = atomicLongArr.compareAndExchange(9, 10L, 999L) // should fail
|
||||
assertTrue(res4 == 90L && atomicLongArr[9] == 90L, "testAtomicLongArrayCompareAndExchange: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndExchange(10, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndExchange(-1, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayCompareAndSet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
val res1 = atomicLongArr.compareAndSet(2, 20L, 222L) // success
|
||||
assertTrue(res1 && atomicLongArr[2] == 222L, "testAtomicLongArrayCompareAndSet: FAIL 1")
|
||||
val res2 = atomicLongArr.compareAndSet(2, 222L, 2222L) // success
|
||||
assertTrue(res2 && atomicLongArr[2] == 2222L, "testAtomicLongArrayCompareAndSet: FAIL 2")
|
||||
val res3 = atomicLongArr.compareAndSet(2, 223L, 22222L) // should fail
|
||||
assertTrue(!res3 && atomicLongArr[2] == 2222L, "testAtomicLongArrayCompareAndSet: FAIL 3")
|
||||
val res4 = atomicLongArr.compareAndSet(9, 10L, 999L) // should fail
|
||||
assertTrue(!res4 && atomicLongArr[9] == 90L, "testAtomicLongArrayCompareAndSet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndSet(10, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndSet(-1, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayGetAndSet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(20L, atomicLongArr.getAndSet(2, 200L), "testAtomicLongArrayGetAndSet: FAIL 1")
|
||||
assertEquals(200L, atomicLongArr.getAndSet(2, 2000L), "testAtomicLongArrayGetAndSet: FAIL 2")
|
||||
assertEquals(2000L, atomicLongArr[2], "testAtomicLongArrayGetAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndSet(22, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndSet(-1, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayGetAndAdd() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndAdd(1, 100L), "testAtomicLongArrayGetAndAdd: FAIL 1")
|
||||
assertEquals(110L, atomicLongArr[1], "testAtomicLongArrayGetAndAdd: FAIL 2")
|
||||
assertEquals(110L, atomicLongArr.getAndAdd(1, -100L), "testAtomicLongArrayGetAndAdd: FAIL 3")
|
||||
assertEquals(10L, atomicLongArr[1], "testAtomicLongArrayGetAndAdd: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndAdd(100, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndAdd(-1, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayAddAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(110L, atomicLongArr.addAndGet(1, 100L), "testAtomicLongArrayAddAndGet: FAIL 1")
|
||||
assertEquals(110L, atomicLongArr[1], "testAtomicLongArrayAddAndGet: FAIL 2")
|
||||
assertEquals(10L, atomicLongArr.addAndGet(1, -100L), "testAtomicLongArrayAddAndGet: FAIL 3")
|
||||
assertEquals(10L, atomicLongArr[1], "testAtomicLongArrayAddAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayGetAndIncrement() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndIncrement(1), "testAtomicLongArrayGetAndIncrement: FAIL 1")
|
||||
assertEquals(11L, atomicLongArr[1], "testAtomicLongArrayGetAndIncrement: FAIL 2")
|
||||
assertEquals(11L, atomicLongArr.getAndIncrement(1), "testAtomicLongArrayGetAndIncrement: FAIL 3")
|
||||
assertEquals(12L, atomicLongArr[1], "testAtomicLongArrayGetAndIncrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndIncrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayIncrementAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(11L, atomicLongArr.incrementAndGet(1), "testAtomicLongArrayIncrementAndGet: FAIL 1")
|
||||
assertEquals(11L, atomicLongArr[1], "testAtomicLongArrayIncrementAndGet: FAIL 2")
|
||||
assertEquals(12L, atomicLongArr.incrementAndGet(1), "testAtomicLongArrayIncrementAndGet: FAIL 3")
|
||||
assertEquals(12L, atomicLongArr[1], "testAtomicLongArrayIncrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.incrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.incrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayGetAndDecrement() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndDecrement(1), "testAtomicLongArrayGetAndDecrement: FAIL 1")
|
||||
assertEquals(9L, atomicLongArr[1], "testAtomicLongArrayGetAndDecrement: FAIL 2")
|
||||
assertEquals(9L, atomicLongArr.getAndDecrement(1), "testAtomicLongArrayGetAndDecrement: FAIL 3")
|
||||
assertEquals(8L, atomicLongArr[1], "testAtomicLongArrayGetAndDecrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndDecrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndDecrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLongArrayDecrementAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(9L, atomicLongArr.decrementAndGet(1), "testAtomicLongArrayDecrementAndGet: FAIL 1")
|
||||
assertEquals(9L, atomicLongArr[1], "testAtomicLongArrayDecrementAndGet: FAIL 2")
|
||||
assertEquals(8L, atomicLongArr.decrementAndGet(1), "testAtomicLongArrayDecrementAndGet: FAIL 3")
|
||||
assertEquals(8L, atomicLongArr[1], "testAtomicLongArrayDecrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.decrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.decrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArrayConstructor() {
|
||||
val arr2 = AtomicArray<String?>(10) { null }
|
||||
assertEquals(arr2[4], null)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicArray<String?>(0) { "aa" }
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicArray<String?>(-5) { "aa" }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArrayGetElement() {
|
||||
val refArr = AtomicArray<String?>(10) { i -> "a$i" }
|
||||
for (i in 0 until refArr.length) {
|
||||
assertEquals("a$i", refArr[i], "testAtomicArrayGetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = refArr[100]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = refArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArraySetElement() {
|
||||
val refArr = AtomicArray<String?>(10) { null }
|
||||
for (i in 0 until refArr.length) {
|
||||
refArr[i] = "a$i"
|
||||
}
|
||||
for (i in 0 until refArr.length) {
|
||||
assertEquals("a$i", refArr[i], "testAtomicArraySetElement: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr[100] = "aaa"
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr[-1] = "aaa"
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArrayCompareAndExchange() {
|
||||
val refArr = AtomicArray<String?>(10) { null }
|
||||
val newValue = "aaa"
|
||||
val res1 = refArr.compareAndExchange(3, null, newValue)
|
||||
assertTrue(res1 == null && refArr[3] == newValue, "testAtomicArrayCompareAndExchange: FAIL 1")
|
||||
val res2 = refArr.compareAndExchange(3, newValue, "bbb")
|
||||
assertTrue(res2 == newValue && refArr[3] == "bbb", "testAtomicArrayCompareAndExchange: FAIL 2")
|
||||
val res3 = refArr.compareAndExchange(3, newValue, "ccc")
|
||||
assertTrue(res3 == "bbb" && refArr[3] == "bbb", "testAtomicArrayCompareAndExchange: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndExchange(10, "aaa", "jdndkj")
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndExchange(-1, "aaa", "jdndkj")
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArrayCompareAndSet() {
|
||||
val refArr = AtomicArray<String?>(10) { null }
|
||||
val newValue = "aaa"
|
||||
val res1 = refArr.compareAndSet(3, null, newValue)
|
||||
assertTrue(res1 && refArr[3] == newValue, "testAtomicArrayCompareAndSet: FAIL 1")
|
||||
val res2 = refArr.compareAndSet(3, newValue, "bbb")
|
||||
assertTrue(res2 && refArr[3] == "bbb", "testAtomicArrayCompareAndSet: FAIL 2")
|
||||
val res3 = refArr.compareAndSet(3, newValue, "ccc")
|
||||
assertTrue(!res3 && refArr[3] == "bbb", "testAtomicArrayCompareAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndSet(10, "aaa", "jdndkj")
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndSet(-1, "aaa", "jdndkj")
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicArrayGetAndSet() {
|
||||
val refArr = AtomicArray<String?>(10) { null }
|
||||
val res4 = refArr.getAndSet(4, "aaa")
|
||||
assertEquals(null, res4, "testAtomicArrayGetAndSet: FAIL 1")
|
||||
val res5 = refArr.getAndSet(4, "bbb")
|
||||
assertEquals("aaa", res5, "testAtomicArrayGetAndSet: FAIL 2")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.getAndSet(10, "aaa")
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.getAndSet(-1, "aaa")
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||
|
||||
package runtime.atomics.atomic_array_stress
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.concurrent.*
|
||||
import kotlin.native.concurrent.*
|
||||
|
||||
fun testAtomicIntArrayStress(workers: Array<Worker>) {
|
||||
val intArr = AtomicIntArray(10)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { intArr }) { intArr ->
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until intArr.length).random()
|
||||
intArr.incrementAndGet(index)
|
||||
}
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0
|
||||
for (i in 0 until intArr.length) {
|
||||
sum += intArr[i]
|
||||
}
|
||||
assertEquals(workers.size * 500, sum)
|
||||
}
|
||||
|
||||
fun testAtomicLongArrayStress(workers: Array<Worker>) {
|
||||
val longArr = AtomicLongArray(10)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { longArr }) { longArr ->
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until longArr.length).random()
|
||||
longArr.incrementAndGet(index)
|
||||
}
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0L
|
||||
for (i in 0 until longArr.length) {
|
||||
sum += longArr[i]
|
||||
}
|
||||
assertEquals(workers.size.toLong() * 500, sum)
|
||||
}
|
||||
|
||||
private class A(val n: Int)
|
||||
|
||||
fun testAtomicArrayStress(workers: Array<Worker>) {
|
||||
val refArr = AtomicArray(10) { A(0) }
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { refArr }) { refArr ->
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until refArr.length).random()
|
||||
while(true) {
|
||||
val cur = refArr[index]
|
||||
val newValue = A(((cur as A).n + 1))
|
||||
if (refArr.compareAndSet(index, cur, newValue)) break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0
|
||||
for (i in 0 until refArr.length) {
|
||||
sum += (refArr[i] as A).n
|
||||
}
|
||||
assertEquals(workers.size * 500, sum)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runStressTest() {
|
||||
val COUNT = 20
|
||||
val workers = Array(COUNT, { _ -> Worker.start()})
|
||||
testAtomicIntArrayStress(workers)
|
||||
testAtomicLongArrayStress(workers)
|
||||
testAtomicArrayStress(workers)
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:OptIn(FreezingIsDeprecated::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
package runtime.atomics.atomic_smoke
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.concurrent.AtomicLong
|
||||
import kotlin.concurrent.AtomicReference
|
||||
import kotlin.concurrent.AtomicNativePtr
|
||||
import kotlin.native.internal.NativePtr
|
||||
|
||||
@Test
|
||||
fun ctor_Int() {
|
||||
val x = AtomicInt(0)
|
||||
assertEquals(x.value, 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ctor_Long() {
|
||||
val x = AtomicLong(0)
|
||||
assertEquals(x.value, 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setter_Int() {
|
||||
val x = AtomicInt(0)
|
||||
x.value = 1
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setter_Long() {
|
||||
val x = AtomicLong(0)
|
||||
x.value = 1
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addAndGet_Int() {
|
||||
val x = AtomicInt(1)
|
||||
val result = x.addAndGet(2)
|
||||
assertEquals(result, 1 + 2)
|
||||
assertEquals(x.value, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addAndGet_Long() {
|
||||
val x = AtomicLong(1)
|
||||
val result = x.addAndGet(2L)
|
||||
assertEquals(result, 1 + 2)
|
||||
assertEquals(x.value, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareAndSwap_Int() {
|
||||
val x = AtomicInt(0)
|
||||
val successValue = x.compareAndExchange(0, 1)
|
||||
assertEquals(successValue, 0)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndExchange(0, 2)
|
||||
assertEquals(failValue, 1)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareAndSwap_Long() {
|
||||
val x = AtomicLong(0)
|
||||
val successValue = x.compareAndExchange(0, 1)
|
||||
assertEquals(successValue, 0)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndExchange(0, 2)
|
||||
assertEquals(failValue, 1)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareAndSet_Int() {
|
||||
val x = AtomicInt(0)
|
||||
val successValue = x.compareAndSet(0, 1)
|
||||
assertTrue(successValue)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndSet(0, 2)
|
||||
assertFalse(failValue)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareAndSet_Long() {
|
||||
val x = AtomicLong(0)
|
||||
val successValue = x.compareAndSet(0, 1)
|
||||
assertTrue(successValue)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndSet(0, 2)
|
||||
assertFalse(failValue)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicInt() {
|
||||
val atomic = AtomicInt(3)
|
||||
assertEquals(3, atomic.value)
|
||||
atomic.value = 5
|
||||
assertEquals(5, atomic.value)
|
||||
assertEquals(5, atomic.getAndSet(6))
|
||||
assertEquals(6, atomic.value)
|
||||
assertTrue(atomic.compareAndSet(6, 8))
|
||||
assertFalse(atomic.compareAndSet(9, 1))
|
||||
assertEquals(8, atomic.value)
|
||||
assertEquals(8, atomic.getAndAdd(5))
|
||||
assertEquals(13, atomic.value)
|
||||
assertEquals(18, atomic.addAndGet(5))
|
||||
assertEquals(18, atomic.getAndIncrement())
|
||||
assertEquals(19, atomic.value)
|
||||
assertEquals(20, atomic.incrementAndGet())
|
||||
assertEquals(20, atomic.value)
|
||||
assertEquals(20, atomic.getAndDecrement())
|
||||
assertEquals(19, atomic.value)
|
||||
assertEquals(18, atomic.decrementAndGet())
|
||||
assertEquals(18, atomic.value)
|
||||
assertEquals(18, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(56, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(56, atomic.compareAndExchange(18, 56))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicLong() {
|
||||
val atomic = AtomicLong(1424920024888900000)
|
||||
assertEquals(1424920024888900000, atomic.value)
|
||||
atomic.value = 2424920024888900000
|
||||
assertEquals(2424920024888900000, atomic.value)
|
||||
assertEquals(2424920024888900000, atomic.getAndSet(3424920024888900000))
|
||||
assertEquals(3424920024888900000, atomic.value)
|
||||
assertTrue(atomic.compareAndSet(3424920024888900000, 4424920024888900000))
|
||||
assertFalse(atomic.compareAndSet(9, 1))
|
||||
assertEquals(4424920024888900000, atomic.value)
|
||||
assertEquals(4424920024888900000, atomic.getAndAdd(100000))
|
||||
assertEquals(4424920024889000000, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.addAndGet(1000000L))
|
||||
assertEquals(4424920024890000000, atomic.getAndIncrement())
|
||||
assertEquals(4424920024890000001, atomic.value)
|
||||
assertEquals(4424920024890000002, atomic.incrementAndGet())
|
||||
assertEquals(4424920024890000002, atomic.value)
|
||||
assertEquals(4424920024890000002, atomic.getAndDecrement())
|
||||
assertEquals(4424920024890000001, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.decrementAndGet())
|
||||
assertEquals(4424920024890000000, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.compareAndExchange(4424920024890000000, 5424920024890000000))
|
||||
assertEquals(5424920024890000000, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(5424920024890000000, atomic.compareAndExchange(18, 56))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtomicRef() {
|
||||
val atomic = AtomicReference<List<String>>(listOf("a", "b", "c"))
|
||||
assertEquals(listOf("a", "b", "c"), atomic.value)
|
||||
atomic.value = listOf("a", "b", "a")
|
||||
assertEquals(listOf("a", "b", "a"), atomic.value)
|
||||
assertEquals(listOf("a", "b", "a"), atomic.getAndSet(listOf("a", "a", "a")))
|
||||
assertEquals(listOf("a", "a", "a"), atomic.value)
|
||||
var cur = atomic.value
|
||||
assertTrue(atomic.compareAndSet(cur, listOf("b", "b", "b")))
|
||||
assertFalse(atomic.compareAndSet(listOf("a", "a", "a"), listOf("b", "b", "b")))
|
||||
assertEquals(listOf("b", "b", "b"), atomic.value)
|
||||
cur = atomic.value
|
||||
assertEquals(listOf("b", "b", "b"), atomic.compareAndExchange(cur, listOf("c", "c", "c")))
|
||||
assertEquals(listOf("c", "c", "c"), atomic.compareAndExchange(cur, listOf("d", "d", "d")))
|
||||
assertEquals(listOf("c", "c", "c"), atomic.compareAndExchange(cur, listOf("c", "c", "c")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativePtr() {
|
||||
val atomic = AtomicNativePtr(NativePtr.NULL)
|
||||
assertEquals(NativePtr.NULL, atomic.value)
|
||||
atomic.value = NativePtr.NULL.plus(10L)
|
||||
assertEquals(10L, atomic.value.toLong())
|
||||
assertTrue(atomic.compareAndSet(NativePtr.NULL.plus(10L), NativePtr.NULL.plus(20L)))
|
||||
assertEquals(20L, atomic.value.toLong())
|
||||
assertFalse(atomic.compareAndSet(NativePtr.NULL.plus(10L), NativePtr.NULL.plus(20L)))
|
||||
assertEquals(20L, atomic.value.toLong())
|
||||
assertEquals(NativePtr.NULL.plus(20L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(30L)))
|
||||
assertEquals(NativePtr.NULL.plus(30L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(40L)))
|
||||
assertEquals(NativePtr.NULL.plus(30L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(50L)))
|
||||
assertEquals(30L, atomic.getAndSet(NativePtr.NULL.plus(55L)).toLong())
|
||||
assertEquals(55L, atomic.value.toLong())
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:OptIn(FreezingIsDeprecated::class)
|
||||
package runtime.atomics.atomic_stress
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.concurrent.*
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.concurrent.AtomicLong
|
||||
import kotlin.concurrent.AtomicReference
|
||||
import kotlin.native.internal.NativePtr
|
||||
|
||||
fun testAtomicIntStress(workers: Array<Worker>) {
|
||||
val atomic = AtomicInt(10)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { atomic }) {
|
||||
atomic -> atomic.addAndGet(1000)
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(10 + 1000 * workers.size, atomic.value)
|
||||
}
|
||||
|
||||
fun testAtomicLongStress(workers: Array<Worker>) {
|
||||
val atomic = AtomicLong(10L)
|
||||
val futures = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { atomic }) {
|
||||
atomic -> atomic.addAndGet(9999999999)
|
||||
}
|
||||
})
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(10L + 9999999999 * workers.size, atomic.value)
|
||||
}
|
||||
|
||||
private class LockFreeStack<T> {
|
||||
private val top = AtomicReference<Node<T>?>(null)
|
||||
|
||||
private class Node<T>(val value: T, val next: Node<T>?)
|
||||
|
||||
fun isEmpty(): Boolean = top.value == null
|
||||
|
||||
fun push(value: T) {
|
||||
while(true) {
|
||||
val cur = top.value
|
||||
val upd = Node(value, cur)
|
||||
if (top.compareAndSet(cur, upd)) return
|
||||
}
|
||||
}
|
||||
|
||||
fun pop(): T? {
|
||||
while(true) {
|
||||
val cur = top.value
|
||||
if (cur == null) return null
|
||||
if (top.compareAndSet(cur, cur.next)) return cur.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testAtomicReferenceStress(workers: Array<Worker>) {
|
||||
val stack = LockFreeStack<Int>()
|
||||
val writers = Array(workers.size, { workerIndex ->
|
||||
workers[workerIndex].execute(TransferMode.SAFE, { stack to workerIndex}) {
|
||||
(stack, workerIndex) -> stack.push(workerIndex)
|
||||
}
|
||||
})
|
||||
writers.forEach { it.result }
|
||||
|
||||
val seen = mutableSetOf<Int>()
|
||||
while(!stack.isEmpty()) {
|
||||
val value = stack.pop()
|
||||
assertNotNull(value)
|
||||
seen.add(value)
|
||||
}
|
||||
assertEquals(workers.size, seen.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runStressTest() {
|
||||
val COUNT = 20
|
||||
val workers = Array(COUNT, { _ -> Worker.start()})
|
||||
|
||||
testAtomicIntStress(workers)
|
||||
testAtomicLongStress(workers)
|
||||
testAtomicReferenceStress(workers)
|
||||
|
||||
workers.forEach {
|
||||
it.requestTermination().result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test.concurrent
|
||||
|
||||
import kotlin.concurrent.*
|
||||
import kotlin.test.*
|
||||
|
||||
class AtomicIntArrayTest {
|
||||
@Test fun ctor() {
|
||||
val arr1 = AtomicIntArray(6)
|
||||
assertEquals(arr1[4], 0)
|
||||
assertEquals(arr1.length, 6)
|
||||
|
||||
val arr2 = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(arr2[4], 40)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicIntArray(0)
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicIntArray(-5)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getter() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
assertEquals(i * 10, atomicIntArr[i], "getter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr[22]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val atomicIntArr = AtomicIntArray(10)
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
atomicIntArr[i] = i * 10
|
||||
}
|
||||
for (i in 0 until atomicIntArr.length) {
|
||||
assertEquals(i * 10, atomicIntArr[i], "setter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicIntArr[22] = 100
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicIntArr[-1] = 100
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(110, atomicIntArr.addAndGet(1, 100), "addAndGet: FAIL 1")
|
||||
assertEquals(110, atomicIntArr[1], "addAndGet: FAIL 2")
|
||||
assertEquals(10, atomicIntArr.addAndGet(1, -100), "addAndGet: FAIL 3")
|
||||
assertEquals(10, atomicIntArr[1], "addAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.addAndGet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
val res1 = atomicIntArr.compareAndExchange(2, 20, 222) // success
|
||||
assertTrue(res1 == 20 && atomicIntArr[2] == 222, "compareAndExchange: FAIL 1")
|
||||
val res2 = atomicIntArr.compareAndExchange(2, 222, 2222) // success
|
||||
assertTrue(res2 == 222 && atomicIntArr[2] == 2222, "compareAndExchange: FAIL 2")
|
||||
val res3 = atomicIntArr.compareAndExchange(2, 223, 22222) // should fail
|
||||
assertTrue(res3 == 2222 && atomicIntArr[2] == 2222, "compareAndExchange: FAIL 3")
|
||||
val res4 = atomicIntArr.compareAndExchange(9, 10, 999) // should fail
|
||||
assertTrue(res4 == 90 && atomicIntArr[9] == 90, "compareAndExchange: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndExchange(10, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndExchange(-1, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
val res1 = atomicIntArr.compareAndSet(2, 20, 222) // success
|
||||
assertTrue(res1 && atomicIntArr[2] == 222, "compareAndSet: FAIL 1")
|
||||
val res2 = atomicIntArr.compareAndSet(2, 222, 2222) // success
|
||||
assertTrue(res2 && atomicIntArr[2] == 2222, "compareAndSet: FAIL 2")
|
||||
val res3 = atomicIntArr.compareAndSet(2, 223, 22222) // should fail
|
||||
assertTrue(!res3 && atomicIntArr[2] == 2222, "compareAndSet: FAIL 3")
|
||||
val res4 = atomicIntArr.compareAndSet(9, 10, 999) // should fail
|
||||
assertTrue(!res4 && atomicIntArr[9] == 90, "compareAndSet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndSet(10, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.compareAndSet(-1, 33535, 39530)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndSet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(20, atomicIntArr.getAndSet(2, 200), "getAndSet: FAIL 1")
|
||||
assertEquals(200, atomicIntArr.getAndSet(2, 2000), "getAndSet: FAIL 2")
|
||||
assertEquals(2000, atomicIntArr[2], "getAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndSet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndSet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndAdd() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndAdd(1, 100), "getAndAdd: FAIL 1")
|
||||
assertEquals(110, atomicIntArr[1], "getAndAdd: FAIL 2")
|
||||
assertEquals(110, atomicIntArr.getAndAdd(1, -100), "getAndAdd: FAIL 3")
|
||||
assertEquals(10, atomicIntArr[1], "getAndAdd: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndAdd(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndAdd(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndIncrement() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndIncrement(1), "getAndIncrement: FAIL 1")
|
||||
assertEquals(11, atomicIntArr[1], "getAndIncrement: FAIL 2")
|
||||
assertEquals(11, atomicIntArr.getAndIncrement(1), "getAndIncrement: FAIL 3")
|
||||
assertEquals(12, atomicIntArr[1], "getAndIncrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndIncrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndIncrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun incrementAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(11, atomicIntArr.incrementAndGet(1), "incrementAndGet: FAIL 1")
|
||||
assertEquals(11, atomicIntArr[1], "incrementAndGet: FAIL 2")
|
||||
assertEquals(12, atomicIntArr.incrementAndGet(1), "incrementAndGet: FAIL 3")
|
||||
assertEquals(12, atomicIntArr[1], "incrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.incrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.incrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndDecrement() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(10, atomicIntArr.getAndDecrement(1), "getAndDecrement: FAIL 1")
|
||||
assertEquals(9, atomicIntArr[1], "getAndDecrement: FAIL 2")
|
||||
assertEquals(9, atomicIntArr.getAndDecrement(1), "getAndDecrement: FAIL 3")
|
||||
assertEquals(8, atomicIntArr[1], "getAndDecrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndDecrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.getAndDecrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun decrementAndGet() {
|
||||
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
|
||||
assertEquals(9, atomicIntArr.decrementAndGet(1), "decrementAndGet: FAIL 1")
|
||||
assertEquals(9, atomicIntArr[1], "decrementAndGet: FAIL 2")
|
||||
assertEquals(8, atomicIntArr.decrementAndGet(1), "decrementAndGet: FAIL 3")
|
||||
assertEquals(8, atomicIntArr[1], "decrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.decrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicIntArr.decrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicIntArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicLongArrayTest {
|
||||
@Test fun ctor() {
|
||||
val arr1 = AtomicLongArray(6)
|
||||
assertEquals(arr1[4], 0L)
|
||||
assertEquals(arr1.length, 6)
|
||||
val arr2 = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(arr2[4], 40L)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicLongArray(0)
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicLongArray(-5)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getter() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
assertEquals(i * 10L, atomicLongArr[i], "getter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr[22]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val atomicLongArr = AtomicLongArray(10)
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
atomicLongArr[i] = i * 10L
|
||||
}
|
||||
for (i in 0 until atomicLongArr.length) {
|
||||
assertEquals(i * 10L, atomicLongArr[i], "setter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr[10] = 3998009
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr[-1] = 3998009
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(110L, atomicLongArr.addAndGet(1, 100L), "addAndGet: FAIL 1")
|
||||
assertEquals(110L, atomicLongArr[1], "addAndGet: FAIL 2")
|
||||
assertEquals(10L, atomicLongArr.addAndGet(1, -100L), "addAndGet: FAIL 3")
|
||||
assertEquals(10L, atomicLongArr[1], "addAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(22, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
val res1 = atomicLongArr.compareAndExchange(2, 20L, 222L) // success
|
||||
assertTrue(res1 == 20L && atomicLongArr[2] == 222L, "compareAndExchange: FAIL 1")
|
||||
val res2 = atomicLongArr.compareAndExchange(2, 222L, 2222L) // success
|
||||
assertTrue(res2 == 222L && atomicLongArr[2] == 2222L, "compareAndExchange: FAIL 2")
|
||||
val res3 = atomicLongArr.compareAndExchange(2, 223L, 22222L) // should fail
|
||||
assertTrue(res3 == 2222L && atomicLongArr[2] == 2222L, "compareAndExchange: FAIL 3")
|
||||
val res4 = atomicLongArr.compareAndExchange(9, 10L, 999L) // should fail
|
||||
assertTrue(res4 == 90L && atomicLongArr[9] == 90L, "compareAndExchange: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndExchange(10, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndExchange(-1, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
val res1 = atomicLongArr.compareAndSet(2, 20L, 222L) // success
|
||||
assertTrue(res1 && atomicLongArr[2] == 222L, "compareAndSet: FAIL 1")
|
||||
val res2 = atomicLongArr.compareAndSet(2, 222L, 2222L) // success
|
||||
assertTrue(res2 && atomicLongArr[2] == 2222L, "compareAndSet: FAIL 2")
|
||||
val res3 = atomicLongArr.compareAndSet(2, 223L, 22222L) // should fail
|
||||
assertTrue(!res3 && atomicLongArr[2] == 2222L, "compareAndSet: FAIL 3")
|
||||
val res4 = atomicLongArr.compareAndSet(9, 10L, 999L) // should fail
|
||||
assertTrue(!res4 && atomicLongArr[9] == 90L, "compareAndSet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndSet(10, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
atomicLongArr.compareAndSet(-1, 9353, 39058308)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndSet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(20L, atomicLongArr.getAndSet(2, 200L), "getAndSet: FAIL 1")
|
||||
assertEquals(200L, atomicLongArr.getAndSet(2, 2000L), "getAndSet: FAIL 2")
|
||||
assertEquals(2000L, atomicLongArr[2], "getAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndSet(22, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndSet(-1, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndAdd() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndAdd(1, 100L), "getAndAdd: FAIL 1")
|
||||
assertEquals(110L, atomicLongArr[1], "getAndAdd: FAIL 2")
|
||||
assertEquals(110L, atomicLongArr.getAndAdd(1, -100L), "getAndAdd: FAIL 3")
|
||||
assertEquals(10L, atomicLongArr[1], "getAndAdd: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndAdd(100, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndAdd(-1, 9353)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndIncrement() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndIncrement(1), "getAndIncrement: FAIL 1")
|
||||
assertEquals(11L, atomicLongArr[1], "getAndIncrement: FAIL 2")
|
||||
assertEquals(11L, atomicLongArr.getAndIncrement(1), "getAndIncrement: FAIL 3")
|
||||
assertEquals(12L, atomicLongArr[1], "getAndIncrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndIncrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.addAndGet(-1, 33535)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun incrementAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(11L, atomicLongArr.incrementAndGet(1), "incrementAndGet: FAIL 1")
|
||||
assertEquals(11L, atomicLongArr[1], "incrementAndGet: FAIL 2")
|
||||
assertEquals(12L, atomicLongArr.incrementAndGet(1), "incrementAndGet: FAIL 3")
|
||||
assertEquals(12L, atomicLongArr[1], "incrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.incrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.incrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndDecrement() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(10L, atomicLongArr.getAndDecrement(1), "getAndDecrement: FAIL 1")
|
||||
assertEquals(9L, atomicLongArr[1], "getAndDecrement: FAIL 2")
|
||||
assertEquals(9L, atomicLongArr.getAndDecrement(1), "getAndDecrement: FAIL 3")
|
||||
assertEquals(8L, atomicLongArr[1], "getAndDecrement: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndDecrement(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.getAndDecrement(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun decrementAndGet() {
|
||||
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
|
||||
assertEquals(9L, atomicLongArr.decrementAndGet(1), "decrementAndGet: FAIL 1")
|
||||
assertEquals(9L, atomicLongArr[1], "decrementAndGet: FAIL 2")
|
||||
assertEquals(8L, atomicLongArr.decrementAndGet(1), "decrementAndGet: FAIL 3")
|
||||
assertEquals(8L, atomicLongArr[1], "decrementAndGet: FAIL 4")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.decrementAndGet(22)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 22 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = atomicLongArr.decrementAndGet(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicLongArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicArrayTest {
|
||||
@Test fun ctor() {
|
||||
val arr2 = AtomicArray<Data?>(10) { null }
|
||||
assertEquals(arr2[4], null)
|
||||
assertEquals(arr2.length, 10)
|
||||
|
||||
val emptyArr = AtomicArray<Data?>(0) { Data(1) }
|
||||
assertEquals(emptyArr.length, 0)
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val arrNegativeSize = AtomicArray<Data?>(-5) { Data(1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getter() {
|
||||
val refArr = AtomicArray<Data?>(10) { i -> Data(i) }
|
||||
for (i in 0 until refArr.length) {
|
||||
assertEquals(Data(i), refArr[i], "getter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = refArr[100]
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
val res = refArr[-1]
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val refArr = AtomicArray<Data?>(10) { null }
|
||||
for (i in 0 until refArr.length) {
|
||||
refArr[i] = Data(i)
|
||||
}
|
||||
for (i in 0 until refArr.length) {
|
||||
assertEquals(Data(i), refArr[i], "setter: FAIL $i")
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr[100] = Data(100)
|
||||
}.let { ex ->
|
||||
assertEquals("The index 100 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr[-1] = Data(-1)
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val refArr = AtomicArray<Data?>(10) { null }
|
||||
val newValue = Data(1)
|
||||
val res1 = refArr.compareAndExchange(3, null, newValue)
|
||||
assertTrue(res1 == null && refArr[3] == newValue, "compareAndExchange: FAIL 1")
|
||||
val res2 = refArr.compareAndExchange(3, newValue, Data(2))
|
||||
assertTrue(res2 == newValue && refArr[3] == Data(2), "compareAndExchange: FAIL 2")
|
||||
val res3 = refArr.compareAndExchange(3, newValue, Data(3))
|
||||
assertTrue(res3 == Data(2) && refArr[3] == Data(2), "compareAndExchange: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndExchange(10, newValue, Data(4))
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndExchange(-1, newValue, Data(4))
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val refArr = AtomicArray<Data?>(10) { null }
|
||||
val newValue = Data(1)
|
||||
val res1 = refArr.compareAndSet(3, null, newValue)
|
||||
assertTrue(res1 && refArr[3] == newValue, "testAtomicArrayCompareAndSet: FAIL 1")
|
||||
val res2 = refArr.compareAndSet(3, newValue, Data(2))
|
||||
assertTrue(res2 && refArr[3] == Data(2), "testAtomicArrayCompareAndSet: FAIL 2")
|
||||
val res3 = refArr.compareAndSet(3, newValue, Data(3))
|
||||
assertTrue(!res3 && refArr[3] == Data(2), "testAtomicArrayCompareAndSet: FAIL 3")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndSet(10, newValue, Data(4))
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.compareAndSet(-1, newValue, Data(4))
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun getAndSet() {
|
||||
val refArr = AtomicArray<Data?>(10) { null }
|
||||
val res4 = refArr.getAndSet(4, Data(1))
|
||||
assertEquals(null, res4, "getAndSet: FAIL 1")
|
||||
val res5 = refArr.getAndSet(4, Data(2))
|
||||
assertEquals(Data(1), res5, "getAndSet: FAIL 2")
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.getAndSet(10, Data(1))
|
||||
}.let { ex ->
|
||||
assertEquals("The index 10 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
assertFailsWith<IndexOutOfBoundsException> {
|
||||
refArr.getAndSet(-1, Data(1))
|
||||
}.let { ex ->
|
||||
assertEquals("The index -1 is out of the bounds of the AtomicArray with size 10.", ex.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test.concurrent
|
||||
|
||||
import kotlin.concurrent.*
|
||||
import kotlin.native.concurrent.Future
|
||||
import kotlin.native.concurrent.TransferMode
|
||||
import kotlin.native.concurrent.Worker
|
||||
import kotlin.test.*
|
||||
|
||||
object ThreadPool {
|
||||
private var _workers: Array<Worker>? = null
|
||||
|
||||
public fun init(threadCount: Int) {
|
||||
_workers = Array(threadCount) { Worker.start() }
|
||||
}
|
||||
|
||||
public fun deinit() {
|
||||
_workers?.forEach {
|
||||
it.requestTermination().result
|
||||
}
|
||||
_workers = null
|
||||
}
|
||||
|
||||
public fun <T> execute(f: (Int) -> T): List<Future<T>> = _workers?.mapIndexed { index, worker ->
|
||||
worker.execute(TransferMode.SAFE, { Pair(f, index) }) { (f, index) ->
|
||||
f(index)
|
||||
}
|
||||
} ?: error("Call ThreadPool.init() first")
|
||||
}
|
||||
|
||||
class AtomicIntStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val atomic = AtomicInt(10)
|
||||
val futures = ThreadPool.execute {
|
||||
atomic.addAndGet(1000)
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(10 + 1000 * futures.size, atomic.value)
|
||||
}
|
||||
|
||||
@Test fun incrementAndGet() {
|
||||
val initial = 15
|
||||
val atomic = AtomicInt(initial)
|
||||
val futures = ThreadPool.execute {
|
||||
atomic.incrementAndGet()
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(initial + futures.size, atomic.value)
|
||||
}
|
||||
|
||||
@Test fun mutex() {
|
||||
val place = AtomicInt(1)
|
||||
val counter = AtomicInt(0)
|
||||
val futures = ThreadPool.execute { index ->
|
||||
// Here we simulate mutex using [place] location to store tag of the current worker.
|
||||
// When it is negative - worker executes exclusively.
|
||||
val tag = index + 1
|
||||
while (place.compareAndExchange(tag, -tag) != tag) {}
|
||||
assertEquals(index + 1, counter.incrementAndGet())
|
||||
// Now, let the next worker run.
|
||||
val previousPlace = place.compareAndExchange(-tag, tag + 1)
|
||||
assertEquals(-tag, previousPlace)
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(futures.size, counter.value)
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicLongStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val atomic = AtomicLong(10L)
|
||||
val futures = ThreadPool.execute {
|
||||
atomic.addAndGet(9999999999)
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertEquals(10L + 9999999999 * futures.size, atomic.value)
|
||||
}
|
||||
}
|
||||
|
||||
private class LockFreeStack<T> {
|
||||
private val top = AtomicReference<Node<T>?>(null)
|
||||
|
||||
private class Node<T>(val value: T, val next: Node<T>?)
|
||||
|
||||
fun isEmpty(): Boolean = top.value == null
|
||||
|
||||
fun push(value: T) {
|
||||
while(true) {
|
||||
val cur = top.value
|
||||
val upd = Node(value, cur)
|
||||
if (top.compareAndSet(cur, upd)) return
|
||||
}
|
||||
}
|
||||
|
||||
fun pop(): T? {
|
||||
while(true) {
|
||||
val cur = top.value
|
||||
if (cur == null) return null
|
||||
if (top.compareAndSet(cur, cur.next)) return cur.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun mutex() {
|
||||
val common = AtomicReference<Data?>(null)
|
||||
val futures = ThreadPool.execute { index ->
|
||||
// Try to publish our own data, until successful, in a tight loop.
|
||||
while (!common.compareAndSet(null, Data(index))) {}
|
||||
}
|
||||
val seen = mutableListOf<Int>()
|
||||
futures.forEach {
|
||||
while(true) {
|
||||
val current = common.value ?: continue
|
||||
// Each worker publishes exactly once
|
||||
assertFalse(seen.contains(current.value))
|
||||
seen.add(current.value)
|
||||
// Let others publish.
|
||||
common.compareAndExchange(current, null)
|
||||
break
|
||||
}
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
assertContentEquals(futures.indices, seen.sorted())
|
||||
}
|
||||
|
||||
@Test fun stackConcurrentPush() {
|
||||
val stack = LockFreeStack<Int>()
|
||||
val writers = ThreadPool.execute {
|
||||
stack.push(it)
|
||||
}
|
||||
writers.forEach { it.result }
|
||||
|
||||
val seen = mutableSetOf<Int>()
|
||||
while(!stack.isEmpty()) {
|
||||
val value = stack.pop()
|
||||
assertNotNull(value)
|
||||
seen.add(value)
|
||||
}
|
||||
assertEquals(writers.size, seen.size)
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicIntArrayStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun incrementAndGet() {
|
||||
val intArr = AtomicIntArray(10)
|
||||
val futures = ThreadPool.execute {
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until intArr.length).random()
|
||||
intArr.incrementAndGet(index)
|
||||
}
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0
|
||||
for (i in 0 until intArr.length) {
|
||||
sum += intArr[i]
|
||||
}
|
||||
assertEquals(futures.size * 500, sum)
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicLongArrayStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun incrementAndGet() {
|
||||
val longArr = AtomicLongArray(10)
|
||||
val futures = ThreadPool.execute {
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until longArr.length).random()
|
||||
longArr.incrementAndGet(index)
|
||||
}
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0L
|
||||
for (i in 0 until longArr.length) {
|
||||
sum += longArr[i]
|
||||
}
|
||||
assertEquals(futures.size.toLong() * 500, sum)
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicArrayStressTest {
|
||||
@BeforeTest fun init() = ThreadPool.init(20)
|
||||
@AfterTest fun deinit() = ThreadPool.deinit()
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val refArr = AtomicArray(10) { Data(0) }
|
||||
val futures = ThreadPool.execute {
|
||||
for (i in 0 until 500) {
|
||||
val index = (0 until refArr.length).random()
|
||||
while(true) {
|
||||
val cur = refArr[index]
|
||||
val newValue = Data(cur.value + 1)
|
||||
if (refArr.compareAndSet(index, cur, newValue)) break
|
||||
}
|
||||
}
|
||||
}
|
||||
futures.forEach {
|
||||
it.result
|
||||
}
|
||||
var sum = 0
|
||||
for (i in 0 until refArr.length) {
|
||||
sum += refArr[i].value
|
||||
}
|
||||
assertEquals(futures.size * 500, sum)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test.concurrent
|
||||
|
||||
import kotlin.concurrent.*
|
||||
import kotlin.native.internal.NativePtr
|
||||
import kotlin.test.*
|
||||
|
||||
data class Data(val value: Int)
|
||||
|
||||
class AtomicIntTest {
|
||||
@Test fun ctor() {
|
||||
val x = AtomicInt(0)
|
||||
assertEquals(x.value, 0)
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val x = AtomicInt(0)
|
||||
x.value = 1
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val x = AtomicInt(1)
|
||||
val result = x.addAndGet(2)
|
||||
assertEquals(result, 1 + 2)
|
||||
assertEquals(x.value, result)
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val x = AtomicInt(0)
|
||||
val successValue = x.compareAndExchange(0, 1)
|
||||
assertEquals(successValue, 0)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndExchange(0, 2)
|
||||
assertEquals(failValue, 1)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val x = AtomicInt(0)
|
||||
val successValue = x.compareAndSet(0, 1)
|
||||
assertTrue(successValue)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndSet(0, 2)
|
||||
assertFalse(failValue)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun smoke() {
|
||||
val atomic = AtomicInt(3)
|
||||
assertEquals(3, atomic.value)
|
||||
atomic.value = 5
|
||||
assertEquals(5, atomic.value)
|
||||
assertEquals(5, atomic.getAndSet(6))
|
||||
assertEquals(6, atomic.value)
|
||||
assertTrue(atomic.compareAndSet(6, 8))
|
||||
assertFalse(atomic.compareAndSet(9, 1))
|
||||
assertEquals(8, atomic.value)
|
||||
assertEquals(8, atomic.getAndAdd(5))
|
||||
assertEquals(13, atomic.value)
|
||||
assertEquals(18, atomic.addAndGet(5))
|
||||
assertEquals(18, atomic.getAndIncrement())
|
||||
assertEquals(19, atomic.value)
|
||||
assertEquals(20, atomic.incrementAndGet())
|
||||
assertEquals(20, atomic.value)
|
||||
assertEquals(20, atomic.getAndDecrement())
|
||||
assertEquals(19, atomic.value)
|
||||
assertEquals(18, atomic.decrementAndGet())
|
||||
assertEquals(18, atomic.value)
|
||||
assertEquals(18, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(56, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(56, atomic.compareAndExchange(18, 56))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicLongTest {
|
||||
@Test fun ctor() {
|
||||
val x = AtomicLong(0)
|
||||
assertEquals(x.value, 0)
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val x = AtomicLong(0)
|
||||
x.value = 1
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun addAndGet() {
|
||||
val x = AtomicLong(1)
|
||||
val result = x.addAndGet(2L)
|
||||
assertEquals(result, 1 + 2)
|
||||
assertEquals(x.value, result)
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val x = AtomicLong(0)
|
||||
val successValue = x.compareAndExchange(0, 1)
|
||||
assertEquals(successValue, 0)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndExchange(0, 2)
|
||||
assertEquals(failValue, 1)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val x = AtomicLong(0)
|
||||
val successValue = x.compareAndSet(0, 1)
|
||||
assertTrue(successValue)
|
||||
assertEquals(x.value, 1)
|
||||
val failValue = x.compareAndSet(0, 2)
|
||||
assertFalse(failValue)
|
||||
assertEquals(x.value, 1)
|
||||
}
|
||||
|
||||
@Test fun smoke() {
|
||||
val atomic = AtomicLong(1424920024888900000)
|
||||
assertEquals(1424920024888900000, atomic.value)
|
||||
atomic.value = 2424920024888900000
|
||||
assertEquals(2424920024888900000, atomic.value)
|
||||
assertEquals(2424920024888900000, atomic.getAndSet(3424920024888900000))
|
||||
assertEquals(3424920024888900000, atomic.value)
|
||||
assertTrue(atomic.compareAndSet(3424920024888900000, 4424920024888900000))
|
||||
assertFalse(atomic.compareAndSet(9, 1))
|
||||
assertEquals(4424920024888900000, atomic.value)
|
||||
assertEquals(4424920024888900000, atomic.getAndAdd(100000))
|
||||
assertEquals(4424920024889000000, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.addAndGet(1000000L))
|
||||
assertEquals(4424920024890000000, atomic.getAndIncrement())
|
||||
assertEquals(4424920024890000001, atomic.value)
|
||||
assertEquals(4424920024890000002, atomic.incrementAndGet())
|
||||
assertEquals(4424920024890000002, atomic.value)
|
||||
assertEquals(4424920024890000002, atomic.getAndDecrement())
|
||||
assertEquals(4424920024890000001, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.decrementAndGet())
|
||||
assertEquals(4424920024890000000, atomic.value)
|
||||
assertEquals(4424920024890000000, atomic.compareAndExchange(4424920024890000000, 5424920024890000000))
|
||||
assertEquals(5424920024890000000, atomic.compareAndExchange(18, 56))
|
||||
assertEquals(5424920024890000000, atomic.compareAndExchange(18, 56))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicReferenceTest {
|
||||
@Test fun ctor() {
|
||||
val x = AtomicReference(Data(1))
|
||||
assertEquals(x.value, Data(1))
|
||||
}
|
||||
|
||||
@Test fun setter() {
|
||||
val x = AtomicReference<Data>(Data(1))
|
||||
x.value = Data(2)
|
||||
assertEquals(x.value, Data(2))
|
||||
}
|
||||
|
||||
@Test fun compareAndExchange() {
|
||||
val initial = Data(1)
|
||||
val new = Data(2)
|
||||
val x = AtomicReference<Data>(initial)
|
||||
val successValue = x.compareAndExchange(initial, new)
|
||||
assertEquals(successValue, initial)
|
||||
assertEquals(x.value, new)
|
||||
val failValue = x.compareAndExchange(initial, Data(3))
|
||||
assertEquals(failValue, new)
|
||||
assertEquals(x.value, new)
|
||||
}
|
||||
|
||||
@Test fun compareAndSet() {
|
||||
val initial = Data(1)
|
||||
val new = Data(2)
|
||||
val x = AtomicReference<Data>(initial)
|
||||
val successValue = x.compareAndSet(initial, new)
|
||||
assertTrue(successValue)
|
||||
assertEquals(x.value, new)
|
||||
val failValue = x.compareAndSet(initial, Data(2))
|
||||
assertFalse(failValue)
|
||||
assertEquals(x.value, new)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun smoke() {
|
||||
val atomic = AtomicReference<List<Data>>(listOf(Data(1), Data(2), Data(3)))
|
||||
assertEquals(listOf(Data(1), Data(2), Data(3)), atomic.value)
|
||||
atomic.value = listOf(Data(1), Data(2), Data(1))
|
||||
assertEquals(listOf(Data(1), Data(2), Data(1)), atomic.value)
|
||||
assertEquals(listOf(Data(1), Data(2), Data(1)), atomic.getAndSet(listOf(Data(1), Data(1), Data(1))))
|
||||
assertEquals(listOf(Data(1), Data(1), Data(1)), atomic.value)
|
||||
var cur = atomic.value
|
||||
assertTrue(atomic.compareAndSet(cur, listOf(Data(2), Data(2), Data(2))))
|
||||
assertFalse(atomic.compareAndSet(listOf(Data(1), Data(1), Data(1)), listOf(Data(2), Data(2), Data(2))))
|
||||
assertEquals(listOf(Data(2), Data(2), Data(2)), atomic.value)
|
||||
cur = atomic.value
|
||||
assertEquals(listOf(Data(2), Data(2), Data(2)), atomic.compareAndExchange(cur, listOf(Data(3), Data(3), Data(3))))
|
||||
assertEquals(listOf(Data(3), Data(3), Data(3)), atomic.compareAndExchange(cur, listOf(Data(4), Data(4), Data(4))))
|
||||
assertEquals(listOf(Data(3), Data(3), Data(3)), atomic.compareAndExchange(cur, listOf(Data(3), Data(3), Data(3))))
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicNativePtrTest {
|
||||
@Test fun smoke() {
|
||||
val atomic = AtomicNativePtr(NativePtr.NULL)
|
||||
assertEquals(NativePtr.NULL, atomic.value)
|
||||
atomic.value = NativePtr.NULL.plus(10L)
|
||||
assertEquals(10L, atomic.value.toLong())
|
||||
assertTrue(atomic.compareAndSet(NativePtr.NULL.plus(10L), NativePtr.NULL.plus(20L)))
|
||||
assertEquals(20L, atomic.value.toLong())
|
||||
assertFalse(atomic.compareAndSet(NativePtr.NULL.plus(10L), NativePtr.NULL.plus(20L)))
|
||||
assertEquals(20L, atomic.value.toLong())
|
||||
assertEquals(NativePtr.NULL.plus(20L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(30L)))
|
||||
assertEquals(NativePtr.NULL.plus(30L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(40L)))
|
||||
assertEquals(NativePtr.NULL.plus(30L), atomic.compareAndExchange(NativePtr.NULL.plus(20L), NativePtr.NULL.plus(50L)))
|
||||
assertEquals(30L, atomic.getAndSet(NativePtr.NULL.plus(55L)).toLong())
|
||||
assertEquals(55L, atomic.value.toLong())
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.TestFactory
|
||||
TC(
|
||||
name = "default",
|
||||
runnerType = TestRunnerType.DEFAULT,
|
||||
freeCompilerArgs = [ENABLE_MPP, STDLIB_IS_A_FRIEND, ENABLE_X_STDLIB_API, ENABLE_X_ENCODING_API, ENABLE_RANGE_UNTIL],
|
||||
freeCompilerArgs = [ENABLE_MPP, STDLIB_IS_A_FRIEND, ENABLE_X_STDLIB_API, ENABLE_X_ENCODING_API, ENABLE_X_FOREIGN_API, ENABLE_RANGE_UNTIL],
|
||||
sourceLocations = [
|
||||
"libraries/stdlib/test/**.kt",
|
||||
"libraries/stdlib/common/test/**.kt",
|
||||
@@ -47,7 +47,7 @@ class StdlibTest : AbstractNativeBlackBoxTest() {
|
||||
TC(
|
||||
name = "default",
|
||||
runnerType = TestRunnerType.DEFAULT,
|
||||
freeCompilerArgs = [ENABLE_MPP, STDLIB_IS_A_FRIEND, ENABLE_X_STDLIB_API, ENABLE_X_ENCODING_API, ENABLE_RANGE_UNTIL,
|
||||
freeCompilerArgs = [ENABLE_MPP, STDLIB_IS_A_FRIEND, ENABLE_X_STDLIB_API, ENABLE_X_ENCODING_API, ENABLE_X_FOREIGN_API, ENABLE_RANGE_UNTIL,
|
||||
"-Xcommon-sources=libraries/stdlib/common/test/jsCollectionFactories.kt",
|
||||
"-Xcommon-sources=libraries/stdlib/common/test/testUtils.kt",
|
||||
"-Xcommon-sources=libraries/stdlib/test/testUtils.kt",
|
||||
@@ -74,5 +74,6 @@ private const val ENABLE_MPP = "-Xmulti-platform"
|
||||
internal const val STDLIB_IS_A_FRIEND = "-friend-modules=$KOTLIN_NATIVE_DISTRIBUTION/klib/common/stdlib"
|
||||
private const val ENABLE_X_STDLIB_API = "-opt-in=kotlin.ExperimentalStdlibApi"
|
||||
private const val ENABLE_X_ENCODING_API = "-opt-in=kotlin.io.encoding.ExperimentalEncodingApi"
|
||||
private const val ENABLE_X_FOREIGN_API = "-opt-in=kotlinx.cinterop.ExperimentalForeignApi"
|
||||
private const val ENABLE_RANGE_UNTIL = "-XXLanguage:+RangeUntilOperator" // keep until 1.8
|
||||
private const val DISABLED_STDLIB_TEST = "test.collections.CollectionTest.abstractCollectionToArray"
|
||||
Reference in New Issue
Block a user