The problem is that compare_exchange_weak
updates the unlatched
variable once it fails. From the documentation of compare_exchange_weak
:
Compares the contents of the atomic object’s contained value with
expected:
– if true, it replaces the contained value with val (like store).
– if false, it replaces expected with the contained value .
I.e., after the first failing compare_exchange_weak
, unlatched
will be updated to true
, so the next loop iteration will try to compare_exchange_weak
true
with true
. This succeeds and you just took a lock that was held by another thread.
Solution:
Make sure to set unlatched
back to false
before each compare_exchange_weak
, e.g.:
while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire)) {
unlatched = false;
}