diff options
Diffstat (limited to 'compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp')
-rw-r--r-- | compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp b/compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp new file mode 100644 index 000000000000..b9fd0c5ad21f --- /dev/null +++ b/compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp @@ -0,0 +1,43 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 +// This is a correct program and tsan should not report a race. +// +// Verify that there is a happens-before relationship between a +// memory_order_release store that happens as part of a successful +// compare_exchange_strong(), and an atomic_thread_fence(memory_order_acquire) +// that happens after a relaxed load. + +#include <atomic> +#include <sanitizer/tsan_interface.h> +#include <stdbool.h> +#include <stdio.h> +#include <thread> + +std::atomic<bool> a; +unsigned int b; +constexpr int loops = 100000; + +void Thread1() { + for (int i = 0; i < loops; ++i) { + while (a.load(std::memory_order_acquire)) { + } + b = i; + bool expected = false; + a.compare_exchange_strong(expected, true, std::memory_order_acq_rel); + } +} + +int main() { + std::thread t(Thread1); + unsigned int sum = 0; + for (int i = 0; i < loops; ++i) { + while (!a.load(std::memory_order_relaxed)) { + } + std::atomic_thread_fence(std::memory_order_acquire); + __tsan_acquire(&a); + sum += b; + a.store(false, std::memory_order_release); + } + t.join(); + fprintf(stderr, "DONE: %u\n", sum); + return 0; +} |