Skip to content

Commit 5094853

Browse files
committed
Refactor: remove interface, make jvmparking delegator stateless. Type return and arguments for delegator functions.
1 parent 959d5df commit 5094853

File tree

17 files changed

+128
-146
lines changed

17 files changed

+128
-146
lines changed

atomicfu/src/androidNative32BitMain/kotlin/kotlinx/atomicfu/parking/PosixParkingDelegator.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@ import kotlinx.cinterop.ptr
1010
import platform.posix.*
1111

1212
@OptIn(ExperimentalForeignApi::class)
13-
internal actual object PosixParkingDelegator : ParkingDelegator {
14-
actual override fun createRef(): Any {
13+
internal actual object ParkingDelegator {
14+
actual fun createRef(): ParkingData {
1515
val mut = nativeHeap.alloc<pthread_mutex_t>().ptr
1616
val cond = nativeHeap.alloc<pthread_cond_t>().ptr
1717
callAndVerifyNative(0) { pthread_mutex_init(mut, null) }
1818
callAndVerifyNative(0) { pthread_cond_init(cond, null) }
1919
return ParkingData(mut, cond)
2020
}
2121

22-
actual override fun wait(ref: Any){
23-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
22+
actual fun wait(ref: ParkingData){
2423
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
2524
while (!ref.wake.value) {
2625
callAndVerifyNative(0) { pthread_cond_wait(ref.cond, ref.mut) }
2726
}
2827
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
2928
}
3029

31-
actual override fun timedWait(ref: Any, nanos: Long): Unit = memScoped {
32-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
30+
actual fun timedWait(ref: ParkingData, nanos: Long): Unit = memScoped {
3331
val ts = alloc<timespec>().ptr
3432

3533
// Add nanos to current time
@@ -50,24 +48,22 @@ internal actual object PosixParkingDelegator : ParkingDelegator {
5048
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5149
}
5250

53-
actual override fun wake(ref: Any) {
54-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
51+
actual fun wake(ref: ParkingData) {
5552
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
5653
ref.wake.value = true
5754
callAndVerifyNative(0) { pthread_cond_signal(ref.cond) }
5855
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5956
}
6057

6158

62-
actual override fun destroyRef(ref: Any) {
63-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
59+
actual fun destroyRef(ref: ParkingData) {
6460
callAndVerifyNative(0) { pthread_mutex_destroy(ref.mut) }
6561
callAndVerifyNative(0) { pthread_cond_destroy(ref.cond) }
6662
nativeHeap.free(ref.mut)
6763
nativeHeap.free(ref.cond)
6864
}
6965

70-
internal data class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
71-
val wake: AtomicBoolean = atomic(false)
72-
}
73-
}
66+
}
67+
internal actual class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
68+
val wake: AtomicBoolean = atomic(false)
69+
}

atomicfu/src/androidNative64BitMain/kotlin/kotlinx/atomicfu/parking/PosixParkingDelegator.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@ import kotlinx.cinterop.ptr
1010
import platform.posix.*
1111

1212
@OptIn(ExperimentalForeignApi::class)
13-
internal actual object PosixParkingDelegator : ParkingDelegator {
14-
actual override fun createRef(): Any {
13+
internal actual object ParkingDelegator {
14+
actual fun createRef(): ParkingData {
1515
val mut = nativeHeap.alloc<pthread_mutex_t>().ptr
1616
val cond = nativeHeap.alloc<pthread_cond_t>().ptr
1717
callAndVerifyNative(0) { pthread_mutex_init(mut, null) }
1818
callAndVerifyNative(0) { pthread_cond_init(cond, null) }
1919
return ParkingData(mut, cond)
2020
}
2121

22-
actual override fun wait(ref: Any) {
23-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
22+
actual fun wait(ref: ParkingData) {
2423
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
2524
while (!ref.wake.value) {
2625
callAndVerifyNative(0) { pthread_cond_wait(ref.cond, ref.mut) }
2726
}
2827
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
2928
}
3029

31-
actual override fun timedWait(ref: Any, nanos: Long): Unit = memScoped {
32-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
30+
actual fun timedWait(ref: ParkingData, nanos: Long): Unit = memScoped {
3331
val ts = alloc<timespec>().ptr
3432

3533
// Add nanos to current time
@@ -50,23 +48,21 @@ internal actual object PosixParkingDelegator : ParkingDelegator {
5048
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5149
}
5250

53-
actual override fun wake(ref: Any) {
54-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
51+
actual fun wake(ref: ParkingData) {
5552
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
5653
ref.wake.value = true
5754
callAndVerifyNative(0) { pthread_cond_signal(ref.cond) }
5855
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5956
}
6057

61-
actual override fun destroyRef(ref: Any) {
62-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
58+
actual fun destroyRef(ref: ParkingData) {
6359
callAndVerifyNative(0) { pthread_mutex_destroy(ref.mut) }
6460
callAndVerifyNative(0) { pthread_cond_destroy(ref.cond) }
6561
nativeHeap.free(ref.mut)
6662
nativeHeap.free(ref.cond)
6763
}
6864

69-
internal data class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
70-
val wake: AtomicBoolean = atomic(false)
71-
}
72-
}
65+
}
66+
internal actual class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
67+
val wake: AtomicBoolean = atomic(false)
68+
}

atomicfu/src/apple32Main/kotlin/kotlinx/atomicfu/parking/PosixParkingDelegator.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@ import kotlinx.cinterop.ptr
1010
import platform.posix.*
1111

1212
@OptIn(ExperimentalForeignApi::class)
13-
internal actual object PosixParkingDelegator : ParkingDelegator {
14-
actual override fun createRef(): Any {
13+
internal actual object ParkingDelegator {
14+
actual fun createRef(): ParkingData {
1515
val mut = nativeHeap.alloc<pthread_mutex_t>().ptr
1616
val cond = nativeHeap.alloc<pthread_cond_t>().ptr
1717
callAndVerifyNative(0) { pthread_mutex_init(mut, null) }
1818
callAndVerifyNative(0) { pthread_cond_init(cond, null) }
1919
return ParkingData(mut, cond)
2020
}
2121

22-
actual override fun wait(ref: Any){
23-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
22+
actual fun wait(ref: ParkingData){
2423
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
2524
while (!ref.wake.value) {
2625
callAndVerifyNative(0) { pthread_cond_wait(ref.cond, ref.mut) }
2726
}
2827
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
2928
}
3029

31-
actual override fun timedWait(ref: Any, nanos: Long): Unit = memScoped {
32-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
30+
actual fun timedWait(ref: ParkingData, nanos: Long): Unit = memScoped {
3331
val ts = alloc<timespec>().ptr
3432

3533
// Add nanos to current time
@@ -50,24 +48,22 @@ internal actual object PosixParkingDelegator : ParkingDelegator {
5048
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5149
}
5250

53-
actual override fun wake(ref: Any) {
54-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
51+
actual fun wake(ref: ParkingData) {
5552
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
5653
ref.wake.value = true
5754
callAndVerifyNative(0) { pthread_cond_signal(ref.cond) }
5855
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5956
}
6057

6158

62-
actual override fun destroyRef(ref: Any) {
63-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
59+
actual fun destroyRef(ref: ParkingData) {
6460
callAndVerifyNative(0) { pthread_mutex_destroy(ref.mut) }
6561
callAndVerifyNative(0) { pthread_cond_destroy(ref.cond) }
6662
nativeHeap.free(ref.mut)
6763
nativeHeap.free(ref.cond)
6864
}
6965

70-
internal data class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
71-
val wake: AtomicBoolean = atomic(false)
72-
}
73-
}
66+
}
67+
internal actual class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
68+
val wake: AtomicBoolean = atomic(false)
69+
}

atomicfu/src/apple64Main/kotlin/kotlinx/atomicfu/parking/PosixParkingDelegator.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,24 @@ import platform.posix.*
1111
import kotlin.toUInt
1212

1313
@OptIn(ExperimentalForeignApi::class)
14-
internal actual object PosixParkingDelegator : ParkingDelegator {
15-
actual override fun createRef(): Any {
14+
internal actual object ParkingDelegator {
15+
actual fun createRef(): ParkingData {
1616
val mut = nativeHeap.alloc<pthread_mutex_t>().ptr
1717
val cond = nativeHeap.alloc<pthread_cond_t>().ptr
1818
callAndVerifyNative(0) { pthread_mutex_init(mut, null) }
1919
callAndVerifyNative(0) { pthread_cond_init(cond, null) }
2020
return ParkingData(mut, cond)
2121
}
2222

23-
actual override fun wait(ref: Any) {
24-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
23+
actual fun wait(ref: ParkingData) {
2524
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
2625
while (!ref.wake.value) {
2726
callAndVerifyNative(0) { pthread_cond_wait(ref.cond, ref.mut) }
2827
}
2928
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
3029
}
3130

32-
actual override fun timedWait(ref: Any, nanos: Long): Unit = memScoped {
33-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
31+
actual fun timedWait(ref: ParkingData, nanos: Long): Unit = memScoped {
3432
val ts = alloc<timespec>().ptr
3533

3634
// Add nanos to current time
@@ -51,23 +49,21 @@ internal actual object PosixParkingDelegator : ParkingDelegator {
5149
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
5250
}
5351

54-
actual override fun wake(ref: Any) {
55-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
52+
actual fun wake(ref: ParkingData) {
5653
callAndVerifyNative(0) { pthread_mutex_lock(ref.mut) }
5754
ref.wake.value = true
5855
callAndVerifyNative(0) { pthread_cond_signal(ref.cond) }
5956
callAndVerifyNative(0) { pthread_mutex_unlock(ref.mut) }
6057
}
6158

62-
actual override fun destroyRef(ref: Any) {
63-
if (ref !is ParkingData) throw IllegalArgumentException("ParkingDelegator got incompatible parking object")
59+
actual fun destroyRef(ref: ParkingData) {
6460
callAndVerifyNative(0) { pthread_mutex_destroy(ref.mut) }
6561
callAndVerifyNative(0) { pthread_cond_destroy(ref.cond) }
6662
nativeHeap.free(ref.mut)
6763
nativeHeap.free(ref.cond)
6864
}
6965

70-
internal data class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
71-
val wake: AtomicBoolean = atomic(false)
72-
}
73-
}
66+
}
67+
internal actual class ParkingData(val mut: CPointer<pthread_mutex_t>, val cond: CPointer<pthread_cond_t>) {
68+
val wake: AtomicBoolean = atomic(false)
69+
}

atomicfu/src/commonMain/kotlin/kotlinx/atomicfu/parking/ParkingDelegator.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ package kotlinx.atomicfu.parking
44
* Internal utility that delegates the thread suspending and resuming calls calls in the platform specific way (darwin, linux, windows).
55
* On jvm delegates to LockSupport.Park.
66
*/
7-
internal interface ParkingDelegator {
8-
fun createRef(): Any
9-
fun wait(ref: Any)
10-
fun timedWait(ref: Any, nanos: Long)
11-
fun wake(ref: Any)
12-
fun destroyRef(ref: Any)
7+
8+
internal expect class ParkingData
9+
10+
internal expect object ParkingDelegator {
11+
fun createRef(): ParkingData
12+
fun wait(ref: ParkingData)
13+
fun timedWait(ref: ParkingData, nanos: Long)
14+
fun wake(ref: ParkingData)
15+
fun destroyRef(ref: ParkingData)
1316
}

atomicfu/src/commonMain/kotlin/kotlinx/atomicfu/parking/ThreadParker.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ import kotlinx.atomicfu.atomic
77
* Should in practice never be used on jvm.
88
*/
99

10-
internal class ThreadParker(private val delegator: ParkingDelegator) {
10+
internal class ThreadParker {
11+
private val delegator = ParkingDelegator
1112
private val state = atomic(STATE_FREE)
12-
private val atomicRef = atomic<Any?>(null)
13+
private val atomicRef = atomic<ParkingData?>(null)
1314

1415
fun park() = parkWith { delegator.wait(atomicRef.value!!) }
1516
fun parkNanos(nanos: Long) = parkWith {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package kotlinx.atomicfu.parking
2+
3+
internal actual class ParkingData
4+
5+
internal actual object ParkingDelegator {
6+
actual fun createRef() = ParkingData()
7+
actual fun wait(ref: ParkingData) {}
8+
actual fun timedWait(ref: ParkingData, nanos: Long) {}
9+
actual fun wake(ref: ParkingData) {}
10+
actual fun destroyRef(ref: ParkingData) {}
11+
}
Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
11
package kotlinx.atomicfu.parking
2-
import java.util.concurrent.atomic.AtomicLong
2+
import java.util.concurrent.atomic.AtomicBoolean
33
import java.util.concurrent.locks.LockSupport
44
import kotlin.time.DurationUnit
55
import kotlin.time.TimeSource.Monotonic
66

7-
internal class JvmParkingDelegator: ParkingDelegator {
8-
private var thread: Thread? = null
9-
private val atomicLong: AtomicLong = AtomicLong(0L)
7+
internal actual object ParkingDelegator {
108

11-
override fun createRef(): Long {
12-
thread = Thread.currentThread()
13-
atomicLong.set(0L)
14-
return 0L
9+
actual fun createRef(): ParkingData {
10+
return ParkingData(Thread.currentThread())
1511
}
1612

17-
override fun wait(ref: Any) {
18-
while (atomicLong.get() == 0L) {
19-
LockSupport.park()
20-
}
13+
actual fun wait(ref: ParkingData) {
14+
while (!ref.wake.get()) LockSupport.park()
2115
}
2216

23-
override fun timedWait(ref: Any, nanos: Long) {
17+
actual fun timedWait(ref: ParkingData, nanos: Long) {
2418
val mark = Monotonic.markNow()
25-
while (atomicLong.get() == 0L) {
26-
LockSupport.parkNanos(nanos)
27-
if (mark.elapsedNow().toLong(DurationUnit.NANOSECONDS) > nanos) break
19+
while (!ref.wake.get()) {
20+
val remainingTime = nanos - mark.elapsedNow().toLong(DurationUnit.NANOSECONDS)
21+
if (remainingTime <= 0) break
22+
LockSupport.parkNanos(remainingTime)
2823
}
2924
}
3025

31-
32-
override fun wake(ref: Any) {
33-
if (atomicLong.compareAndSet(0L, 1L)) {
34-
LockSupport.unpark(thread)
26+
actual fun wake(ref: ParkingData) {
27+
if (ref.wake.compareAndSet(false, true)) {
28+
LockSupport.unpark(ref.thread)
3529
}
3630
}
3731

3832

39-
override fun destroyRef(ref: Any) {
40-
thread = null
33+
actual fun destroyRef(ref: ParkingData) {
4134
}
42-
}
35+
}
36+
37+
internal actual class ParkingData(val thread: Thread, val wake: AtomicBoolean = AtomicBoolean(false))

atomicfu/src/jvmMain/kotlin/kotlinx/atomicfu/parking/KThread.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package kotlinx.atomicfu.parking
22

33
actual class KThread internal actual constructor() {
4-
internal val parker = ThreadParker(JvmParkingDelegator())
4+
internal val parker = ThreadParker()
55
actual companion object {
66
actual fun currentThread(): KThread = localKThread.get()
77
}

0 commit comments

Comments
 (0)