[clang] Handle __declspec() attributes in using
[llvm-project.git] / compiler-rt / lib / tsan / tests / rtl / tsan_mutex.cpp
blobd45014b2ec86a529b62ad6116e1b70d7c152c943
1 //===-- tsan_mutex.cpp ----------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
17 #include <stdint.h>
19 namespace __tsan {
21 TEST_F(ThreadSanitizer, BasicMutex) {
22 ScopedThread t;
23 UserMutex m;
24 t.Create(m);
26 t.Lock(m);
27 t.Unlock(m);
29 CHECK(t.TryLock(m));
30 t.Unlock(m);
32 t.Lock(m);
33 CHECK(!t.TryLock(m));
34 t.Unlock(m);
36 t.Destroy(m);
39 TEST_F(ThreadSanitizer, BasicSpinMutex) {
40 ScopedThread t;
41 UserMutex m(UserMutex::Spin);
42 t.Create(m);
44 t.Lock(m);
45 t.Unlock(m);
47 CHECK(t.TryLock(m));
48 t.Unlock(m);
50 t.Lock(m);
51 CHECK(!t.TryLock(m));
52 t.Unlock(m);
54 t.Destroy(m);
57 TEST_F(ThreadSanitizer, BasicRwMutex) {
58 ScopedThread t;
59 UserMutex m(UserMutex::RW);
60 t.Create(m);
62 t.Lock(m);
63 t.Unlock(m);
65 CHECK(t.TryLock(m));
66 t.Unlock(m);
68 t.Lock(m);
69 CHECK(!t.TryLock(m));
70 t.Unlock(m);
72 t.ReadLock(m);
73 t.ReadUnlock(m);
75 CHECK(t.TryReadLock(m));
76 t.ReadUnlock(m);
78 t.Lock(m);
79 CHECK(!t.TryReadLock(m));
80 t.Unlock(m);
82 t.ReadLock(m);
83 CHECK(!t.TryLock(m));
84 t.ReadUnlock(m);
86 t.ReadLock(m);
87 CHECK(t.TryReadLock(m));
88 t.ReadUnlock(m);
89 t.ReadUnlock(m);
91 t.Destroy(m);
94 TEST_F(ThreadSanitizer, Mutex) {
95 UserMutex m;
96 MainThread t0;
97 t0.Create(m);
99 ScopedThread t1, t2;
100 MemLoc l;
101 t1.Lock(m);
102 t1.Write1(l);
103 t1.Unlock(m);
104 t2.Lock(m);
105 t2.Write1(l);
106 t2.Unlock(m);
107 t2.Destroy(m);
110 TEST_F(ThreadSanitizer, SpinMutex) {
111 UserMutex m(UserMutex::Spin);
112 MainThread t0;
113 t0.Create(m);
115 ScopedThread t1, t2;
116 MemLoc l;
117 t1.Lock(m);
118 t1.Write1(l);
119 t1.Unlock(m);
120 t2.Lock(m);
121 t2.Write1(l);
122 t2.Unlock(m);
123 t2.Destroy(m);
126 TEST_F(ThreadSanitizer, RwMutex) {
127 UserMutex m(UserMutex::RW);
128 MainThread t0;
129 t0.Create(m);
131 ScopedThread t1, t2, t3;
132 MemLoc l;
133 t1.Lock(m);
134 t1.Write1(l);
135 t1.Unlock(m);
136 t2.Lock(m);
137 t2.Write1(l);
138 t2.Unlock(m);
139 t1.ReadLock(m);
140 t3.ReadLock(m);
141 t1.Read1(l);
142 t3.Read1(l);
143 t1.ReadUnlock(m);
144 t3.ReadUnlock(m);
145 t2.Lock(m);
146 t2.Write1(l);
147 t2.Unlock(m);
148 t2.Destroy(m);
151 TEST_F(ThreadSanitizer, StaticMutex) {
152 // Emulates statically initialized mutex.
153 UserMutex m;
154 m.StaticInit();
156 ScopedThread t1, t2;
157 t1.Lock(m);
158 t1.Unlock(m);
159 t2.Lock(m);
160 t2.Unlock(m);
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);
170 __tsan_read4(val);
171 CHECK_EQ(*val, 42);
173 return 0;
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++) {
182 ScopedThread t1;
183 (void)t1;
185 // Create the singleton.
186 int val = 42;
187 __tsan_write4(&val);
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++) {
205 ScopedThread t1;
206 (void)t1;
208 // Create the stop flag.
209 atomic_uintptr_t flag;
210 __tsan_release(&flag);
211 atomic_store(&flag, 0, memory_order_release);
212 // Read it a lot.
213 for (int i = 0; i < kIters; i++) {
214 uptr v = atomic_load(&flag, memory_order_acquire);
215 __tsan_acquire(&flag);
216 CHECK_EQ(v, 0);
220 } // namespace __tsan