Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 1 | /* |
Roman Elizarov | 1f74a2d | 2018-06-29 19:19:45 +0300 | [diff] [blame^] | 2 | * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 3 | */ |
| 4 | |
| 5 | package kotlinx.coroutines.experimental.internal |
| 6 | |
Roman Elizarov | 5d94a26 | 2017-12-28 00:23:39 +0300 | [diff] [blame] | 7 | import com.devexperts.dxlab.lincheck.* |
| 8 | import com.devexperts.dxlab.lincheck.annotations.* |
| 9 | import com.devexperts.dxlab.lincheck.paramgen.* |
| 10 | import com.devexperts.dxlab.lincheck.stress.* |
Roman Elizarov | 6129c94 | 2018-01-10 17:34:40 +0300 | [diff] [blame] | 11 | import kotlinx.coroutines.experimental.* |
Roman Elizarov | 5d94a26 | 2017-12-28 00:23:39 +0300 | [diff] [blame] | 12 | import kotlin.test.* |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 13 | |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 14 | @Param(name = "value", gen = IntGen::class, conf = "1:3") |
Roman Elizarov | 6129c94 | 2018-01-10 17:34:40 +0300 | [diff] [blame] | 15 | class LockFreeListLinearizabilityTest : TestBase() { |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 16 | class Node(val value: Int): LockFreeLinkedListNode() |
| 17 | |
| 18 | lateinit var q: LockFreeLinkedListHead |
| 19 | |
| 20 | @Reset |
| 21 | fun reset() { |
| 22 | q = LockFreeLinkedListHead() |
| 23 | } |
| 24 | |
| 25 | @Operation |
| 26 | fun addLast(@Param(name = "value") value: Int) { |
| 27 | q.addLast(Node(value)) |
| 28 | } |
| 29 | |
| 30 | @Operation |
| 31 | fun addLastIfNotSame(@Param(name = "value") value: Int) { |
| 32 | q.addLastIfPrev(Node(value)) { !it.isSame(value) } |
| 33 | } |
| 34 | |
| 35 | @Operation |
| 36 | fun removeFirst(): Int? { |
| 37 | val node = q.removeFirstOrNull() ?: return null |
| 38 | return (node as Node).value |
| 39 | } |
| 40 | |
| 41 | @Operation |
| 42 | fun removeFirstOrPeekIfNotSame(@Param(name = "value") value: Int): Int? { |
| 43 | val node = q.removeFirstIfIsInstanceOfOrPeekIf<Node> { !it.isSame(value) } ?: return null |
Vsevolod Tolstopyatov | 87f2faa | 2018-04-30 22:53:02 +0300 | [diff] [blame] | 44 | return node.value |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | fun Any.isSame(value: Int) = this is Node && this.value == value |
| 48 | |
| 49 | @Test |
| 50 | fun testAddRemoveLinearizability() { |
Roman Elizarov | 6129c94 | 2018-01-10 17:34:40 +0300 | [diff] [blame] | 51 | val options = StressOptions() |
| 52 | .iterations(100) |
| 53 | .invocationsPerIteration(1000 * stressTestMultiplier) |
| 54 | .addThread(1, 2) |
| 55 | .addThread(1, 2) |
| 56 | .addThread(1, 2) |
| 57 | .addThread(1, 2) |
| 58 | LinChecker.check(LockFreeListLinearizabilityTest::class.java, options) |
Roman Elizarov | 475c043 | 2017-07-11 22:12:42 +0300 | [diff] [blame] | 59 | } |
| 60 | } |