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 Clausenvoid 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 Clausenint 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