@@ -13,15 +13,46 @@ import kotlinx.coroutines.*
13
13
import kotlinx.coroutines.internal.*
14
14
import kotlin.test.*
15
15
16
+ internal data class Snapshot (val elements : List <Int >, val isClosed : Boolean ) {
17
+ constructor (q: LockFreeTaskQueue <Int >) : this (q.map { it }, q.isClosed())
18
+ }
19
+
16
20
@OpGroupConfig.OpGroupConfigs (OpGroupConfig (name = " consumer" , nonParallel = true ))
17
21
@Param(name = " value" , gen = IntGen ::class , conf = " 1:3" )
18
- class LockFreeTaskQueueLinearizabilityTest : TestBase () {
22
+ class LockFreeTaskQueueLinearizabilityTestSC : LockFreeTaskQueueLinearizabilityTestBase () {
23
+ private val q: LockFreeTaskQueue <Int > = LockFreeTaskQueue (singleConsumer = true )
24
+
25
+ @Operation
26
+ fun close () = q.close()
27
+
28
+ @Operation
29
+ fun addLast (@Param(name = " value" ) value : Int ) = q.addLast(value)
19
30
20
- private companion object {
21
- var singleConsumer = false
31
+ /* *
32
+ * Note, that removeFirstOrNull is not linearizable w.r.t. to addLast, so here
33
+ * we test only linearizability of close.
34
+ */
35
+ // @Operation(group = "consumer")
36
+ // fun removeFirstOrNull() = q.removeFirstOrNull()
37
+
38
+ @Test
39
+ fun testSC () = linTest()
40
+
41
+ override fun equals (other : Any? ): Boolean {
42
+ if (this == = other) return true
43
+ if (javaClass != other?.javaClass) return false
44
+
45
+ other as LockFreeTaskQueueLinearizabilityTestSC
46
+
47
+ return Snapshot (q) == Snapshot (other.q)
22
48
}
23
49
24
- private val q: LockFreeTaskQueue <Int > = LockFreeTaskQueue (singleConsumer)
50
+ override fun hashCode (): Int = Snapshot (q).hashCode()
51
+ }
52
+
53
+ @Param(name = " value" , gen = IntGen ::class , conf = " 1:3" )
54
+ class LockFreeTaskQueueLinearizabilityTestMC : LockFreeTaskQueueLinearizabilityTestBase () {
55
+ private val q: LockFreeTaskQueue <Int > = LockFreeTaskQueue (singleConsumer = false )
25
56
26
57
@Operation
27
58
fun close () = q.close()
@@ -37,22 +68,26 @@ class LockFreeTaskQueueLinearizabilityTest : TestBase() {
37
68
// fun removeFirstOrNull() = q.removeFirstOrNull()
38
69
39
70
@Test
40
- fun testLinearizabilitySC () {
41
- singleConsumer = true
42
- linTest()
43
- }
71
+ fun testMC () = linTest()
44
72
45
- @Test
46
- fun testLinearizabilityMC () {
47
- singleConsumer = false
48
- linTest()
73
+ override fun equals (other : Any? ): Boolean {
74
+ if (this == = other) return true
75
+ if (javaClass != other?.javaClass) return false
76
+
77
+ other as LockFreeTaskQueueLinearizabilityTestMC
78
+
79
+ return Snapshot (q) == Snapshot (other.q)
49
80
}
50
81
51
- private fun linTest () {
82
+ override fun hashCode (): Int = Snapshot (q).hashCode()
83
+ }
84
+
85
+ open class LockFreeTaskQueueLinearizabilityTestBase : TestBase () {
86
+ fun linTest () {
52
87
val options = StressOptions ()
53
88
.iterations(100 * stressTestMultiplierSqrt)
54
89
.invocationsPerIteration(1000 * stressTestMultiplierSqrt)
55
- .threads(3 )
56
- LinChecker .check(LockFreeTaskQueueLinearizabilityTest ::class .java, options)
90
+ .threads(2 )
91
+ LinChecker .check(this ::class .java, options)
57
92
}
58
93
}
0 commit comments