Skip to content

Commit e1f89db

Browse files
committed
Extract test ops to separate methods for better stack traces
1 parent b60d94c commit e1f89db

File tree

1 file changed

+57
-34
lines changed

1 file changed

+57
-34
lines changed

kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListAtomicStressLFTest.kt

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class LockFreeLinkedListAtomicStressLFTest : TestBase() {
3333

3434
data class IntNode(val i: Int) : LockFreeLinkedListNode()
3535

36-
private val TEST_DURATION_SEC = 5 * stressTestMultiplier
36+
private val TEST_DURATION_SEC = 50 * stressTestMultiplier
3737

3838
val nLists = 4
3939
val nAdderThreads = 4
@@ -55,23 +55,23 @@ class LockFreeLinkedListAtomicStressLFTest : TestBase() {
5555
0 -> {
5656
val list = lists[rnd.nextInt(nLists)]
5757
val node = IntNode(threadId)
58-
list.addLast(node)
58+
addLastOp(list, node)
5959
randomSpinWaitIntermission()
60-
tryRemove(node)
60+
tryRemoveOp(node)
6161
}
6262
1 -> {
6363
// just to test conditional add
6464
val list = lists[rnd.nextInt(nLists)]
6565
val node = IntNode(threadId)
66-
assertTrue(list.addLastIf(node, { true }))
66+
addLastIfTrueOp(list, node)
6767
randomSpinWaitIntermission()
68-
tryRemove(node)
68+
tryRemoveOp(node)
6969
}
7070
2 -> {
7171
// just to test failed conditional add and burn some time
7272
val list = lists[rnd.nextInt(nLists)]
7373
val node = IntNode(threadId)
74-
assertFalse(list.addLastIf(node, { false }))
74+
addLastIfFalseOp(list, node)
7575
}
7676
3 -> {
7777
// add two atomically
@@ -82,22 +82,11 @@ class LockFreeLinkedListAtomicStressLFTest : TestBase() {
8282
val list2 = lists[idx2]
8383
val node1 = IntNode(threadId)
8484
val node2 = IntNode(-threadId - 1)
85-
val add1 = list1.describeAddLast(node1)
86-
val add2 = list2.describeAddLast(node2)
87-
val op = object : AtomicOp<Any?>() {
88-
override fun prepare(affected: Any?): Any? =
89-
add1.prepare(this) ?:
90-
add2.prepare(this)
91-
override fun complete(affected: Any?, failure: Any?) {
92-
add1.complete(this, failure)
93-
add2.complete(this, failure)
94-
}
95-
}
96-
assertTrue(op.perform(null) == null)
85+
addTwoOp(list1, node1, list2, node2)
9786
randomSpinWaitIntermission()
98-
tryRemove(node1)
87+
tryRemoveOp(node1)
9988
randomSpinWaitIntermission()
100-
tryRemove(node2)
89+
tryRemoveOp(node2)
10190
}
10291
else -> error("Cannot happen")
10392
}
@@ -111,19 +100,7 @@ class LockFreeLinkedListAtomicStressLFTest : TestBase() {
111100
check(idx1 < idx2) // that is our global order
112101
val list1 = lists[idx1]
113102
val list2 = lists[idx2]
114-
val remove1 = list1.describeRemoveFirst()
115-
val remove2 = list2.describeRemoveFirst()
116-
val op = object : AtomicOp<Any?>() {
117-
override fun prepare(affected: Any?): Any? =
118-
remove1.prepare(this) ?:
119-
remove2.prepare(this)
120-
override fun complete(affected: Any?, failure: Any?) {
121-
remove1.complete(this, failure)
122-
remove2.complete(this, failure)
123-
}
124-
}
125-
val success = op.perform(null) == null
126-
if (success) removed.addAndGet(2)
103+
removeTwoOp(list1, list2)
127104
}
128105
}
129106
env.performTest(TEST_DURATION_SEC) {
@@ -141,10 +118,56 @@ class LockFreeLinkedListAtomicStressLFTest : TestBase() {
141118
lists.forEach { it.validate() }
142119
}
143120

144-
private fun tryRemove(node: IntNode) {
121+
private fun addLastOp(list: LockFreeLinkedListHead, node: IntNode) {
122+
list.addLast(node)
123+
}
124+
125+
private fun addLastIfTrueOp(list: LockFreeLinkedListHead, node: IntNode) {
126+
assertTrue(list.addLastIf(node, { true }))
127+
}
128+
129+
private fun addLastIfFalseOp(list: LockFreeLinkedListHead, node: IntNode) {
130+
assertFalse(list.addLastIf(node, { false }))
131+
}
132+
133+
private fun addTwoOp(list1: LockFreeLinkedListHead, node1: IntNode, list2: LockFreeLinkedListHead, node2: IntNode) {
134+
val add1 = list1.describeAddLast(node1)
135+
val add2 = list2.describeAddLast(node2)
136+
val op = object : AtomicOp<Any?>() {
137+
override fun prepare(affected: Any?): Any? =
138+
add1.prepare(this) ?:
139+
add2.prepare(this)
140+
141+
override fun complete(affected: Any?, failure: Any?) {
142+
add1.complete(this, failure)
143+
add2.complete(this, failure)
144+
}
145+
}
146+
assertTrue(op.perform(null) == null)
147+
}
148+
149+
private fun tryRemoveOp(node: IntNode) {
145150
if (node.remove())
146151
undone.incrementAndGet()
147152
else
148153
missed.incrementAndGet()
149154
}
155+
156+
private fun removeTwoOp(list1: LockFreeLinkedListHead, list2: LockFreeLinkedListHead) {
157+
val remove1 = list1.describeRemoveFirst()
158+
val remove2 = list2.describeRemoveFirst()
159+
val op = object : AtomicOp<Any?>() {
160+
override fun prepare(affected: Any?): Any? =
161+
remove1.prepare(this) ?:
162+
remove2.prepare(this)
163+
164+
override fun complete(affected: Any?, failure: Any?) {
165+
remove1.complete(this, failure)
166+
remove2.complete(this, failure)
167+
}
168+
}
169+
val success = op.perform(null) == null
170+
if (success) removed.addAndGet(2)
171+
}
172+
150173
}

0 commit comments

Comments
 (0)