<lambda>null1 package kotlinx.atomicfu.locks
2
3 import kotlin.concurrent.AtomicInt
4 import kotlin.native.concurrent.*
5 import kotlin.test.*
6
7 private const val iterations = 100
8 private const val nWorkers = 4
9 private const val increments = 500
10 private const val nLocks = 5
11
12 class SynchronizedTest {
13
14 @Test
15 fun stressCounterTest() {
16 repeat(iterations) {
17 val workers = Array(nWorkers) { Worker.start() }
18 val counter = AtomicInt(0).freeze()
19 val so = SynchronizedObject().freeze()
20 workers.forEach { worker ->
21 worker.execute(TransferMode.SAFE, {
22 counter to so
23 }) { (count, lock) ->
24 repeat(increments) {
25 val nestedLocks = (1..3).random()
26 repeat(nestedLocks) { lock.lock() }
27 val oldValue = count.value
28 count.value = oldValue + 1
29 repeat(nestedLocks) { lock.unlock() }
30 }
31 }
32 }
33 workers.forEach {
34 it.requestTermination().result
35 }
36 assertEquals(nWorkers * increments, counter.value)
37 }
38 }
39
40
41 @Test
42 fun manyLocksTest() {
43 repeat(iterations) {
44 val workers = Array(nWorkers) { Worker.start() }
45 val counters = Array(nLocks) { AtomicInt(0) }.freeze()
46 val locks = Array(nLocks) { SynchronizedObject() }.freeze()
47 workers.forEach { worker ->
48 worker.execute(TransferMode.SAFE, {
49 counters to locks
50 }) { (counters, locks) ->
51 locks.forEachIndexed { i, lock ->
52 repeat(increments) {
53 synchronized(lock) {
54 val oldValue = counters[i].value
55 counters[i].value = oldValue + 1
56 }
57 }
58 }
59 }
60 }
61 workers.forEach {
62 it.requestTermination().result
63 }
64 assertEquals(nWorkers * nLocks * increments, counters.sumBy { it.value })
65 }
66 }
67
68 @Test
69 fun stressReentrantLockTest() {
70 repeat(iterations) {
71 val workers = Array(nWorkers) { Worker.start() }
72 val counter = AtomicInt(0).freeze()
73 val so = ReentrantLock().freeze()
74 workers.forEach { worker ->
75 worker.execute(TransferMode.SAFE, {
76 counter to so
77 }) { (count, lock) ->
78 repeat(increments) {
79 while (!lock.tryLock()) {}
80 val oldValue = count.value
81 count.value = oldValue + 1
82 lock.unlock()
83 }
84 }
85 }
86 workers.forEach {
87 it.requestTermination().result
88 }
89 assertEquals(nWorkers * increments, counter.value)
90 }
91 }
92
93 @Test
94 fun nestedReentrantLockTest() {
95 repeat(iterations) {
96 val workers = Array(nWorkers) { Worker.start() }
97 val counter = AtomicInt(0).freeze()
98 val so = ReentrantLock().freeze()
99 workers.forEach { worker ->
100 worker.execute(TransferMode.SAFE, {
101 counter to so
102 }) { (count, lock) ->
103 repeat(increments) {
104 lock.lock()
105 val nestedLocks = (1..3).random()
106 repeat(nestedLocks) {
107 assertTrue(lock.tryLock())
108 }
109 val oldValue = count.value
110 count.value = oldValue + 1
111 repeat(nestedLocks + 1) { lock.unlock() }
112 }
113 }
114 }
115 workers.forEach {
116 it.requestTermination().result
117 }
118 assertEquals(nWorkers * increments, counter.value)
119 }
120 }
121 }