Files
kotlin-fork/compiler/testData/codegen/box/volatile/intrinsicWithInlineFunction.kt
T
Pavel Kunyavskiy 488d24296a [K/N]: Allow invocation of volatile intrinsics on inline function constant arguments.
Invocation of atomic intrinsics is only allowed on property references that are known at compile time. This commit makes it possible to also invoke intrinsics on a constant property reference getter passed as an argument.
See KT-58359

Co-authored-by: Pavel Kunyavskiy <Pavel.Kunyavskiy@jetbrains.com>

Merge-request: KT-MR-10413
Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
2023-07-24 17:45:16 +00:00

44 lines
1.3 KiB
Kotlin
Vendored

// TARGET_BACKEND: NATIVE
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
import kotlin.concurrent.*
import kotlin.reflect.*
class Box(@Volatile var value1: Int, @Volatile var value2: Int)
inline fun wrapCas(crossinline refGetter: () -> KMutableProperty0<Int>, expected: Int, new: Int) = refGetter().compareAndExchangeField(expected, new)
inline fun wrapCasTwice(crossinline refGetter: () -> KMutableProperty0<Int>, expected: Int, new: Int) = wrapCas(refGetter, expected, new)
class A(@Volatile var x: String) {
fun add(str: String) {
update({ -> (this::x)}) { x + str }
}
}
inline fun update(crossinline refGetter: () -> KMutableProperty0<String>, action: (String) -> String) {
while (true) {
val cur = refGetter().get()
val upd = action(cur)
if (refGetter().compareAndSetField(cur, upd)) return
}
}
fun box() : String {
val box = Box(1, 2)
wrapCas({ -> (box::value1)}, 1, 3)
wrapCas({ -> (box::value2)}, 2, 4)
if (box.value1 != 3) return "FAIL 1"
if (box.value2 != 4) return "FAIL 2"
wrapCasTwice({ -> (box::value1)}, 3, 5)
wrapCasTwice( { -> (box::value2)}, 4, 6)
if (box.value1 != 5) return "FAIL 3"
if (box.value2 != 6) return "FAIL 4"
val a = A("a")
a.add("b")
if (a.x != "ab") return "FAIL 5"
return "OK"
}