xref: /llvm-project/compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp (revision f467cc9caf37fcf6b3523271f977585c39372d55)
1 // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t && %run %t 2>&1
2 // This is a correct program and tsan should not report a race.
3 //
4 // Verify that there is a happens-before relationship between a
5 // memory_order_release store that happens as part of a successful
6 // compare_exchange_strong(), and an atomic_thread_fence(memory_order_acquire)
7 // that happens after a relaxed load.
8 
9 #include <atomic>
10 #include <sanitizer/tsan_interface.h>
11 #include <stdbool.h>
12 #include <stdio.h>
13 #include <thread>
14 
15 std::atomic<bool> a;
16 unsigned int b;
17 constexpr int loops = 100000;
18 
Thread1()19 void Thread1() {
20   for (int i = 0; i < loops; ++i) {
21     while (a.load(std::memory_order_acquire)) {
22     }
23     b = i;
24     bool expected = false;
25     a.compare_exchange_strong(expected, true, std::memory_order_acq_rel);
26   }
27 }
28 
main()29 int main() {
30   std::thread t(Thread1);
31   unsigned int sum = 0;
32   for (int i = 0; i < loops; ++i) {
33     while (!a.load(std::memory_order_relaxed)) {
34     }
35     std::atomic_thread_fence(std::memory_order_acquire);
36     __tsan_acquire(&a);
37     sum += b;
38     a.store(false, std::memory_order_release);
39   }
40   t.join();
41   fprintf(stderr, "DONE: %u\n", sum);
42   return 0;
43 }
44