// http://preshing.com/20120515/memory-reordering-caught-in-the-act #include "xorshift32.h" #include #include #include #include #include #include using namespace std::literals; int x, y, r1, r2; unsigned reorders = 0, iterations = 0; std::atomic run(true); std::binary_semaphore s1(1), s2(1), s3(1), s4(1); thread_local xorshift32 rng; void t1() { while (run) { s1.acquire(); while (rng() & 7) ; x = 1; std::atomic_thread_fence(std::memory_order_seq_cst); r1 = y; s3.release(); } } void t2() { while (run) { s2.acquire(); while (rng() & 7) ; y = 1; std::atomic_thread_fence(std::memory_order_seq_cst); r2 = x; s4.release(); } } void t3() { while (run) { x = 0; y = 0; s1.release(); s2.release(); s3.acquire(); s4.acquire(); if (r1 == 0 && r2 == 0) ++reorders; ++iterations; } } int main() { s1.acquire(); s2.acquire(); s3.acquire(); s4.acquire(); std::jthread t[] = {std::jthread(t1), std::jthread(t2), std::jthread(t3)}; std::this_thread::sleep_for(500ms); run = false; s1.release(); s2.release(); s3.release(); s4.release(); std::cout << reorders << " reorders detected after " << iterations << " iterations" << std::endl; }