Mercurial > hg > CbC > CbC_llvm
view compiler-rt/test/tsan/compare_exchange.cpp @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 2e18cbf3894f |
children |
line wrap: on
line source
// RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t && %deflake %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck --check-prefix=CHECK-REPORT %s #include <atomic> #include <cassert> #include <stdio.h> #include <thread> #define NUM_ORDS 16 #define NUM_THREADS NUM_ORDS * 2 struct node { int val; }; std::atomic<node *> _nodes[NUM_THREADS] = {}; void f1(int i) { auto n = new node(); n->val = 42; _nodes[i].store(n, std::memory_order_release); } template <int version> void f2(int i, std::memory_order mo, std::memory_order fmo) { node *expected = nullptr; while (expected == nullptr) { _nodes[i].compare_exchange_weak(expected, nullptr, mo, fmo); }; ++expected->val; assert(expected->val == 43); } struct MemOrdSuccFail { std::memory_order mo; std::memory_order fmo; }; MemOrdSuccFail OrdList[NUM_ORDS] = { {std::memory_order_release, std::memory_order_relaxed}, {std::memory_order_release, std::memory_order_acquire}, {std::memory_order_release, std::memory_order_consume}, {std::memory_order_release, std::memory_order_seq_cst}, {std::memory_order_acq_rel, std::memory_order_relaxed}, {std::memory_order_acq_rel, std::memory_order_acquire}, {std::memory_order_acq_rel, std::memory_order_consume}, {std::memory_order_acq_rel, std::memory_order_seq_cst}, {std::memory_order_seq_cst, std::memory_order_relaxed}, {std::memory_order_seq_cst, std::memory_order_acquire}, {std::memory_order_seq_cst, std::memory_order_consume}, {std::memory_order_seq_cst, std::memory_order_seq_cst}, {std::memory_order_relaxed, std::memory_order_relaxed}, {std::memory_order_relaxed, std::memory_order_acquire}, {std::memory_order_relaxed, std::memory_order_consume}, {std::memory_order_relaxed, std::memory_order_seq_cst}, }; int main() { std::thread threads[NUM_THREADS]; int ords = 0; // Instantiate a new f2 for each MO so we can dedup reports and actually // make sure relaxed FMO triggers a warning for every different MO. for (unsigned t = 0; t < 8; t += 2) { threads[t] = std::thread(f1, t); threads[t + 1] = std::thread(f2<0>, t, OrdList[ords].mo, OrdList[ords].fmo); threads[t].join(); threads[t + 1].join(); ords++; } for (unsigned t = 8; t < 16; t += 2) { threads[t] = std::thread(f1, t); threads[t + 1] = std::thread(f2<1>, t, OrdList[ords].mo, OrdList[ords].fmo); threads[t].join(); threads[t + 1].join(); ords++; } for (unsigned t = 16; t < 24; t += 2) { threads[t] = std::thread(f1, t); threads[t + 1] = std::thread(f2<2>, t, OrdList[ords].mo, OrdList[ords].fmo); threads[t].join(); threads[t + 1].join(); ords++; } for (unsigned t = 24; t < 32; t += 2) { threads[t] = std::thread(f1, t); threads[t + 1] = std::thread(f2<3>, t, OrdList[ords].mo, OrdList[ords].fmo); threads[t].join(); threads[t + 1].join(); ords++; } fprintf(stderr, "DONE\n"); return 0; } // CHECK-REPORT: WARNING: ThreadSanitizer: data race // CHECK-REPORT: WARNING: ThreadSanitizer: data race // CHECK-REPORT: WARNING: ThreadSanitizer: data race // CHECK-REPORT: WARNING: ThreadSanitizer: data race // CHECK-REPORT: DONE // CHECK-REPORT: ThreadSanitizer: reported 4 warnings