Skip to content

Commit 6f82783

Browse files
committed
Cache removed references in LockFreeLinkedList (save two objects on repeated adds/removes to list)
1 parent 41c5c8b commit 6f82783

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedList.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ internal open class LockFreeLinkedListNode {
1919
private var _next: Any = this // DoubleLinkedNode | Removed | CondAdd
2020
@Volatile
2121
private var prev: Any = this // DoubleLinkedNode | Removed
22+
@Volatile
23+
private var removedRef: Removed? = null // lazily cached removed ref to this
2224

2325
private companion object {
2426
@JvmStatic
@@ -27,13 +29,18 @@ internal open class LockFreeLinkedListNode {
2729
@JvmStatic
2830
val PREV: AtomicReferenceFieldUpdater<Node, Any> =
2931
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")
3135
}
3236

3337
private class Removed(val ref: Node) {
3438
override fun toString(): String = "Removed[$ref]"
3539
}
3640

41+
private fun removed(): Removed =
42+
removedRef ?: Removed(this).also { REMOVED_REF.lazySet(this, it) }
43+
3744
@PublishedApi
3845
internal abstract class CondAdd {
3946
internal lateinit var newNode: Node
@@ -145,7 +152,7 @@ internal open class LockFreeLinkedListNode {
145152
while (true) { // lock-free loop on next
146153
val next = this.next
147154
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())) {
149156
// was removed successfully (linearized remove) -- fixup the list
150157
helpDelete()
151158
next.helpInsert(prev.unwrap())
@@ -166,7 +173,7 @@ internal open class LockFreeLinkedListNode {
166173
while (true) { // lock-free loop on prev
167174
val prev = this.prev
168175
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
170177
}
171178
}
172179

0 commit comments

Comments
 (0)