@@ -19,6 +19,8 @@ internal open class LockFreeLinkedListNode {
19
19
private var _next : Any = this // DoubleLinkedNode | Removed | CondAdd
20
20
@Volatile
21
21
private var prev: Any = this // DoubleLinkedNode | Removed
22
+ @Volatile
23
+ private var removedRef: Removed ? = null // lazily cached removed ref to this
22
24
23
25
private companion object {
24
26
@JvmStatic
@@ -27,13 +29,18 @@ internal open class LockFreeLinkedListNode {
27
29
@JvmStatic
28
30
val PREV : AtomicReferenceFieldUpdater <Node , Any > =
29
31
AtomicReferenceFieldUpdater .newUpdater(Node ::class .java, Any ::class .java, " prev" )
30
-
32
+ @JvmStatic
33
+ val REMOVED_REF : AtomicReferenceFieldUpdater <Node , Removed ?> =
34
+ AtomicReferenceFieldUpdater .newUpdater(Node ::class .java, Removed ::class .java, " removedRef" )
31
35
}
32
36
33
37
private class Removed (val ref : Node ) {
34
38
override fun toString (): String = " Removed[$ref ]"
35
39
}
36
40
41
+ private fun removed (): Removed =
42
+ removedRef ? : Removed (this ).also { REMOVED_REF .lazySet(this , it) }
43
+
37
44
@PublishedApi
38
45
internal abstract class CondAdd {
39
46
internal lateinit var newNode: Node
@@ -145,7 +152,7 @@ internal open class LockFreeLinkedListNode {
145
152
while (true ) { // lock-free loop on next
146
153
val next = this .next
147
154
if (next is Removed ) return false // was already removed -- don't try to help (original thread will take care)
148
- if (NEXT .compareAndSet(this , next, Removed (next as Node ))) {
155
+ if (NEXT .compareAndSet(this , next, (next as Node ).removed( ))) {
149
156
// was removed successfully (linearized remove) -- fixup the list
150
157
helpDelete()
151
158
next.helpInsert(prev.unwrap())
@@ -166,7 +173,7 @@ internal open class LockFreeLinkedListNode {
166
173
while (true ) { // lock-free loop on prev
167
174
val prev = this .prev
168
175
if (prev is Removed ) return prev.ref
169
- if (PREV .compareAndSet(this , prev, Removed (prev as Node ))) return prev
176
+ if (PREV .compareAndSet(this , prev, (prev as Node ).removed( ))) return prev
170
177
}
171
178
}
172
179
0 commit comments