@@ -128,10 +128,16 @@ internal open class SemaphoreAndMutexImpl(private val permits: Int, acquiredPerm
128
128
private val tail: AtomicRef <SemaphoreSegment >
129
129
private val enqIdx = atomic(0L )
130
130
131
+ /* *
132
+ This value is used in [SemaphoreSegment.isLeftmostOrProcessed].
133
+ It helps to detect when the `prev` reference of the segment should be cleaned.
134
+ */
135
+ internal val headId: Long get() = head.value.id
136
+
131
137
init {
132
138
require(permits > 0 ) { " Semaphore should have at least 1 permit, but had $permits " }
133
139
require(acquiredPermits in 0 .. permits) { " The number of acquired permits should be in 0..$permits " }
134
- val s = SemaphoreSegment (0 , null )
140
+ val s = SemaphoreSegment (0 , null , this )
135
141
head = atomic(s)
136
142
tail = atomic(s)
137
143
}
@@ -317,7 +323,6 @@ internal open class SemaphoreAndMutexImpl(private val permits: Int, acquiredPerm
317
323
val createNewSegment = ::createSegment
318
324
val segment = this .head.findSegmentAndMoveForward(id, startFrom = curHead,
319
325
createNewSegment = createNewSegment).segment // cannot be closed
320
- segment.cleanPrev()
321
326
if (segment.id > id) return false
322
327
val i = (deqIdx % SEGMENT_SIZE ).toInt()
323
328
val cellState = segment.getAndSet(i, PERMIT ) // set PERMIT and retrieve the prev cell state
@@ -356,12 +361,19 @@ private class SemaphoreImpl(
356
361
permits : Int , acquiredPermits : Int
357
362
): SemaphoreAndMutexImpl(permits, acquiredPermits), Semaphore
358
363
359
- private fun createSegment (id : Long , prev : SemaphoreSegment ? ) = SemaphoreSegment (id, prev)
364
+ private fun createSegment (id : Long , prev : SemaphoreSegment ) = SemaphoreSegment (
365
+ id = id,
366
+ prev = prev,
367
+ semaphore = prev.semaphore
368
+ )
360
369
361
- private class SemaphoreSegment (id : Long , prev : SemaphoreSegment ? ) : Segment<SemaphoreSegment>(id, prev) {
370
+ private class SemaphoreSegment (
371
+ id : Long , prev : SemaphoreSegment ? ,
372
+ val semaphore : SemaphoreAndMutexImpl
373
+ ) : Segment<SemaphoreSegment>(id, prev) {
362
374
val acquirers = atomicArrayOfNulls<Any ?>(SEGMENT_SIZE )
363
375
override val numberOfSlots: Int get() = SEGMENT_SIZE
364
- override val isLeftmostOrProcessed: Boolean get() = false // Does not impact semaphore implementation
376
+ override val isLeftmostOrProcessed: Boolean get() = id <= semaphore.headId
365
377
366
378
@Suppress(" NOTHING_TO_INLINE" )
367
379
inline fun get (index : Int ): Any? = acquirers[index].value
0 commit comments