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.