std::atomic<std::size_t> latch;
std::atomic<std::size_t> count;
void wait_for_latch() {
auto expected_count = latch.load(std::memory_order_relaxed);
if (expected_count == 0) {
std::this_thread::yield();
} else {
while (!latch.compare_exchange_weak(expected_count, expected_count + 1)) {
expected_count = latch.load(std::memory_order_relaxed);
}
auto old_count = count.load(std::memory_order_relaxed);
while (!count.compare_exchange_weak(old_count, old_count + 1)) {
old_count = count.load(std::memory_order_relaxed);
}
if (old_count + 1 == expected_count) {
latch.store(0, std::memory_order_relaxed);
count.store(0, std::memory_order_relaxed);
}
}
}