Arsen
03/03/2025, 11:09 AMkotlinx.coroutines.sync.Mutex
provides `cache visibility`/`happen before` guarantees? 🤔
It looks like optimistic path works via `atomic`(compare-and-set) permits.
Consider case when Dispatcher has multiple threads:
0. mutex unlocked
1. Coroutine A
from Thread A
on CPU Core A
increments counter (optimistic path via atomics)
2. mutex unlocked
3. Coroutine B
from Thread B
on CPU Core B
increments counter (optimistic path via atomics)
I understand why it works when mutex
is locked (cas fails) so coroutine
suspends, then(eventually) resume
happens which involves some task to be scheduled to Dispatcher i.e. interaction with smth like `LinkedBlockingQueue`(put() and take() provides happens before
).
What forces counter
value to be synced across cores? if in both cases only atomics
were involved? Maybe that's not true and some other synchronization also happens that I'm not aware of.Arsen
03/03/2025, 11:22 AMvar counter = 0
val mutex = Mutex()
runBlocking {
repeat(1_000_000) {
scope.launch {
withContext(Dispatchers.IO) {
mutex.withLock {
counter++
}
}
}
}
scope.coroutineContext.job.children.forEach { it.join() }
}
println("Counter: $counter")
Dmitry Khalanskiy [JB]
03/03/2025, 1:06 PMweakCompareAndSet
is the version of compareAndSet
without the happens-before guarantees.