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
15std::atomic<bool> a;
16unsigned int b;
17constexpr int loops = 100000;
18
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
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, format: "DONE: %u\n", sum);
42 return 0;
43}
44

source code of compiler-rt/test/tsan/compare_exchange_acquire_fence.cpp