<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 }