11package kotlinx.atomicfu.locks
22
33import platform.posix.*
4- import interop.*
5- import kotlinx.cinterop.*
6- import kotlin.native.internal.NativePtr
74import kotlinx.atomicfu.locks.SynchronizedObject.Status.*
8- import kotlin.concurrent.AtomicNativePtr
95import kotlin.concurrent.AtomicReference
10- import kotlin.native.concurrent.*
116
127public actual open class SynchronizedObject {
138
@@ -23,6 +18,7 @@ public actual open class SynchronizedObject {
2318 if (lock.compareAndSet(state, thinLock))
2419 return
2520 }
21+
2622 THIN -> {
2723 if (currentThreadId == state.ownerThreadId) {
2824 // reentrant lock
@@ -46,13 +42,16 @@ public actual open class SynchronizedObject {
4642 }
4743 }
4844 }
45+
4946 FAT -> {
5047 if (currentThreadId == state.ownerThreadId) {
5148 // reentrant lock
52- val nestedFatLock = LockState (FAT , state.nestedLocks + 1 , state.waiters, state.ownerThreadId, state.mutex)
49+ val nestedFatLock =
50+ LockState (FAT , state.nestedLocks + 1 , state.waiters, state.ownerThreadId, state.mutex)
5351 if (lock.compareAndSet(state, nestedFatLock)) return
5452 } else if (state.ownerThreadId != null ) {
55- val fatLock = LockState (FAT , state.nestedLocks, state.waiters + 1 , state.ownerThreadId, state.mutex)
53+ val fatLock =
54+ LockState (FAT , state.nestedLocks, state.waiters + 1 , state.ownerThreadId, state.mutex)
5655 if (lock.compareAndSet(state, fatLock)) {
5756 fatLock.mutex!! .lock()
5857 tryLockAfterResume(currentThreadId)
@@ -74,7 +73,8 @@ public actual open class SynchronizedObject {
7473 return true
7574 } else {
7675 if (currentThreadId == state.ownerThreadId) {
77- val nestedLock = LockState (state.status, state.nestedLocks + 1 , state.waiters, currentThreadId, state.mutex)
76+ val nestedLock =
77+ LockState (state.status, state.nestedLocks + 1 , state.waiters, currentThreadId, state.mutex)
7878 if (lock.compareAndSet(state, nestedLock))
7979 return true
8080 } else {
@@ -103,6 +103,7 @@ public actual open class SynchronizedObject {
103103 return
104104 }
105105 }
106+
106107 FAT -> {
107108 if (state.nestedLocks == 1 ) {
108109 // last nested unlock -> release completely, resume some waiter
@@ -119,6 +120,7 @@ public actual open class SynchronizedObject {
119120 return
120121 }
121122 }
123+
122124 else -> error(" It is not possible to unlock the mutex that is not obtained" )
123125 }
124126 }
@@ -146,14 +148,10 @@ public actual open class SynchronizedObject {
146148 val nestedLocks : Int ,
147149 val waiters : Int ,
148150 val ownerThreadId : pthread_t? = null ,
149- val mutex : CPointer <mutex_node_t> ? = null
151+ val mutex : NativeMutexNode ? = null
150152 )
151153
152154 protected enum class Status { UNLOCKED , THIN , FAT }
153-
154- private fun CPointer<mutex_node_t>.lock () = lock(this .pointed.mutex)
155-
156- private fun CPointer<mutex_node_t>.unlock () = unlock(this .pointed.mutex)
157155}
158156
159157public actual fun reentrantLock () = ReentrantLock ()
@@ -183,37 +181,40 @@ private const val INITIAL_POOL_CAPACITY = 64
183181private val mutexPool by lazy { MutexPool (INITIAL_POOL_CAPACITY ) }
184182
185183class MutexPool (capacity : Int ) {
186- private val top = AtomicNativePtr ( NativePtr . NULL )
184+ private val top = AtomicReference < NativeMutexNode ?>( null )
187185
188- private val mutexes = nativeHeap.allocArray < mutex_node_t > (capacity) { mutex_node_init(ptr ) }
186+ private val mutexes = Array < NativeMutexNode >(capacity) { NativeMutexNode ( ) }
189187
190188 init {
191- for (i in 0 until capacity) {
192- release(interpretCPointer< mutex_node_t> (mutexes.rawValue.plus(i * sizeOf< mutex_node_t> ()))!! )
189+ // Immediately form a stack
190+ for (mutex in mutexes) {
191+ release(mutex)
193192 }
194193 }
195194
196- private fun allocMutexNode () = nativeHeap.alloc < mutex_node_t > { mutex_node_init(ptr) }.ptr
195+ private fun allocMutexNode () = NativeMutexNode ()
197196
198- fun allocate (): CPointer <mutex_node_t> = pop() ? : allocMutexNode()
197+ fun allocate (): NativeMutexNode = pop() ? : allocMutexNode()
199198
200- fun release (mutexNode : CPointer <mutex_node_t> ) {
199+ fun release (mutexNode : NativeMutexNode ) {
201200 while (true ) {
202- val oldTop = interpretCPointer < mutex_node_t > ( top.value)
203- mutexNode.pointed. next = oldTop
204- if (top.compareAndSet(oldTop.rawValue , mutexNode.rawValue))
201+ val oldTop = top.value
202+ mutexNode.next = oldTop
203+ if (top.compareAndSet(oldTop, mutexNode)) {
205204 return
205+ }
206206 }
207207 }
208208
209- private fun pop (): CPointer <mutex_node_t> ? {
209+ private fun pop (): NativeMutexNode ? {
210210 while (true ) {
211- val oldTop = interpretCPointer < mutex_node_t > ( top.value)
212- if (oldTop.rawValue == = NativePtr . NULL )
211+ val oldTop = top.value
212+ if (oldTop == null )
213213 return null
214- val newHead = oldTop!! .pointed .next
215- if (top.compareAndSet(oldTop.rawValue , newHead.rawValue))
214+ val newHead = oldTop.next
215+ if (top.compareAndSet(oldTop, newHead)) {
216216 return oldTop
217+ }
217218 }
218219 }
219220}
0 commit comments