]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //===-- tsan_mutex_test.cc ------------------------------------------------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file is a part of ThreadSanitizer (TSan), a race detector. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | #include "sanitizer_common/sanitizer_internal_defs.h" | |
14 | #include "sanitizer_common/sanitizer_atomic.h" | |
15 | #include "sanitizer_common/sanitizer_common.h" | |
16 | #include "sanitizer_common/sanitizer_mutex.h" | |
17 | #include "tsan_mutex.h" | |
18 | #include "gtest/gtest.h" | |
19 | ||
20 | namespace __tsan { | |
21 | ||
22 | template<typename MutexType> | |
23 | class TestData { | |
24 | public: | |
25 | explicit TestData(MutexType *mtx) | |
26 | : mtx_(mtx) { | |
27 | for (int i = 0; i < kSize; i++) | |
28 | data_[i] = 0; | |
29 | } | |
30 | ||
31 | void Write() { | |
32 | Lock l(mtx_); | |
33 | T v0 = data_[0]; | |
34 | for (int i = 0; i < kSize; i++) { | |
35 | CHECK_EQ(data_[i], v0); | |
36 | data_[i]++; | |
37 | } | |
38 | } | |
39 | ||
40 | void Read() { | |
41 | ReadLock l(mtx_); | |
42 | T v0 = data_[0]; | |
43 | for (int i = 0; i < kSize; i++) { | |
44 | CHECK_EQ(data_[i], v0); | |
45 | } | |
46 | } | |
47 | ||
48 | void Backoff() { | |
49 | volatile T data[kSize] = {}; | |
50 | for (int i = 0; i < kSize; i++) { | |
51 | data[i]++; | |
52 | CHECK_EQ(data[i], 1); | |
53 | } | |
54 | } | |
55 | ||
56 | private: | |
57 | typedef GenericScopedLock<MutexType> Lock; | |
58 | static const int kSize = 64; | |
59 | typedef u64 T; | |
60 | MutexType *mtx_; | |
61 | char pad_[kCacheLineSize]; | |
62 | T data_[kSize]; | |
63 | }; | |
64 | ||
65 | const int kThreads = 8; | |
66 | const int kWriteRate = 1024; | |
92a42be0 | 67 | #if SANITIZER_DEBUG |
1a4d82fc JJ |
68 | const int kIters = 16*1024; |
69 | #else | |
70 | const int kIters = 64*1024; | |
71 | #endif | |
72 | ||
73 | template<typename MutexType> | |
74 | static void *write_mutex_thread(void *param) { | |
75 | TestData<MutexType> *data = (TestData<MutexType>*)param; | |
76 | for (int i = 0; i < kIters; i++) { | |
77 | data->Write(); | |
78 | data->Backoff(); | |
79 | } | |
80 | return 0; | |
81 | } | |
82 | ||
83 | template<typename MutexType> | |
84 | static void *read_mutex_thread(void *param) { | |
85 | TestData<MutexType> *data = (TestData<MutexType>*)param; | |
86 | for (int i = 0; i < kIters; i++) { | |
87 | if ((i % kWriteRate) == 0) | |
88 | data->Write(); | |
89 | else | |
90 | data->Read(); | |
91 | data->Backoff(); | |
92 | } | |
93 | return 0; | |
94 | } | |
95 | ||
96 | TEST(Mutex, Write) { | |
97 | Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations); | |
98 | TestData<Mutex> data(&mtx); | |
99 | pthread_t threads[kThreads]; | |
100 | for (int i = 0; i < kThreads; i++) | |
101 | pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data); | |
102 | for (int i = 0; i < kThreads; i++) | |
103 | pthread_join(threads[i], 0); | |
104 | } | |
105 | ||
106 | TEST(Mutex, ReadWrite) { | |
107 | Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations); | |
108 | TestData<Mutex> data(&mtx); | |
109 | pthread_t threads[kThreads]; | |
110 | for (int i = 0; i < kThreads; i++) | |
111 | pthread_create(&threads[i], 0, read_mutex_thread<Mutex>, &data); | |
112 | for (int i = 0; i < kThreads; i++) | |
113 | pthread_join(threads[i], 0); | |
114 | } | |
115 | ||
116 | TEST(Mutex, SpinWrite) { | |
117 | SpinMutex mtx; | |
118 | TestData<SpinMutex> data(&mtx); | |
119 | pthread_t threads[kThreads]; | |
120 | for (int i = 0; i < kThreads; i++) | |
121 | pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data); | |
122 | for (int i = 0; i < kThreads; i++) | |
123 | pthread_join(threads[i], 0); | |
124 | } | |
125 | ||
126 | } // namespace __tsan |