xref: /llvm-project/compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp (revision f467cc9caf37fcf6b3523271f977585c39372d55)
1*f467cc9cSDave Clausen // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t && %run %t 2>&1
247625e47SDave Clausen // This is a correct program and tsan should not report a race.
347625e47SDave Clausen //
447625e47SDave Clausen // Verify that there is a happens-before relationship between a
547625e47SDave Clausen // memory_order_release store that happens as part of a successful
647625e47SDave Clausen // compare_exchange_strong(), and an atomic_thread_fence(memory_order_acquire)
747625e47SDave Clausen // that happens after a relaxed load.
847625e47SDave Clausen 
947625e47SDave Clausen #include <atomic>
1047625e47SDave Clausen #include <sanitizer/tsan_interface.h>
1147625e47SDave Clausen #include <stdbool.h>
1247625e47SDave Clausen #include <stdio.h>
1347625e47SDave Clausen #include <thread>
1447625e47SDave Clausen 
1547625e47SDave Clausen std::atomic<bool> a;
1647625e47SDave Clausen unsigned int b;
1747625e47SDave Clausen constexpr int loops = 100000;
1847625e47SDave Clausen 
Thread1()1947625e47SDave Clausen void Thread1() {
2047625e47SDave Clausen   for (int i = 0; i < loops; ++i) {
2147625e47SDave Clausen     while (a.load(std::memory_order_acquire)) {
2247625e47SDave Clausen     }
2347625e47SDave Clausen     b = i;
2447625e47SDave Clausen     bool expected = false;
2547625e47SDave Clausen     a.compare_exchange_strong(expected, true, std::memory_order_acq_rel);
2647625e47SDave Clausen   }
2747625e47SDave Clausen }
2847625e47SDave Clausen 
main()2947625e47SDave Clausen int main() {
3047625e47SDave Clausen   std::thread t(Thread1);
3147625e47SDave Clausen   unsigned int sum = 0;
3247625e47SDave Clausen   for (int i = 0; i < loops; ++i) {
3347625e47SDave Clausen     while (!a.load(std::memory_order_relaxed)) {
3447625e47SDave Clausen     }
3547625e47SDave Clausen     std::atomic_thread_fence(std::memory_order_acquire);
3647625e47SDave Clausen     __tsan_acquire(&a);
3747625e47SDave Clausen     sum += b;
3847625e47SDave Clausen     a.store(false, std::memory_order_release);
3947625e47SDave Clausen   }
4047625e47SDave Clausen   t.join();
4147625e47SDave Clausen   fprintf(stderr, "DONE: %u\n", sum);
4247625e47SDave Clausen   return 0;
4347625e47SDave Clausen }
44