1 //===-- tsan_mutex.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_atomic.h"
13 #include "tsan_interface.h"
14 #include "tsan_interface_ann.h"
15 #include "tsan_test_util.h"
16 #include "gtest/gtest.h"
21 TEST_F(ThreadSanitizer
, BasicMutex
) {
39 TEST_F(ThreadSanitizer
, BasicSpinMutex
) {
41 UserMutex
m(UserMutex::Spin
);
57 TEST_F(ThreadSanitizer
, BasicRwMutex
) {
59 UserMutex
m(UserMutex::RW
);
75 CHECK(t
.TryReadLock(m
));
79 CHECK(!t
.TryReadLock(m
));
87 CHECK(t
.TryReadLock(m
));
94 TEST_F(ThreadSanitizer
, Mutex
) {
110 TEST_F(ThreadSanitizer
, SpinMutex
) {
111 UserMutex
m(UserMutex::Spin
);
126 TEST_F(ThreadSanitizer
, RwMutex
) {
127 UserMutex
m(UserMutex::RW
);
131 ScopedThread t1
, t2
, t3
;
151 TEST_F(ThreadSanitizer
, StaticMutex
) {
152 // Emulates statically initialized mutex.
162 MainThread().Destroy(m
);
165 static void *singleton_thread(void *param
) {
166 atomic_uintptr_t
*singleton
= (atomic_uintptr_t
*)param
;
167 for (int i
= 0; i
< 4*1024*1024; i
++) {
168 int *val
= (int *)atomic_load(singleton
, memory_order_acquire
);
169 __tsan_acquire(singleton
);
176 TEST(DISABLED_BENCH_ThreadSanitizer
, Singleton
) {
177 const int kClockSize
= 100;
178 const int kThreadCount
= 8;
180 // Puff off thread's clock.
181 for (int i
= 0; i
< kClockSize
; i
++) {
185 // Create the singleton.
188 atomic_uintptr_t singleton
;
189 __tsan_release(&singleton
);
190 atomic_store(&singleton
, (uintptr_t)&val
, memory_order_release
);
191 // Create reader threads.
192 pthread_t threads
[kThreadCount
];
193 for (int t
= 0; t
< kThreadCount
; t
++)
194 pthread_create(&threads
[t
], 0, singleton_thread
, &singleton
);
195 for (int t
= 0; t
< kThreadCount
; t
++)
196 pthread_join(threads
[t
], 0);
199 TEST(DISABLED_BENCH_ThreadSanitizer
, StopFlag
) {
200 const int kClockSize
= 100;
201 const int kIters
= 16*1024*1024;
203 // Puff off thread's clock.
204 for (int i
= 0; i
< kClockSize
; i
++) {
208 // Create the stop flag.
209 atomic_uintptr_t flag
;
210 __tsan_release(&flag
);
211 atomic_store(&flag
, 0, memory_order_release
);
213 for (int i
= 0; i
< kIters
; i
++) {
214 uptr v
= atomic_load(&flag
, memory_order_acquire
);
215 __tsan_acquire(&flag
);
220 } // namespace __tsan