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()19void 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()29int 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