Skip to content

Commit 513f023

Browse files
committed
tsan/asan: add SpinMutex to sanitizer_common
llvm-svn: 159439
1 parent 7a9fa7d commit 513f023

File tree

6 files changed

+74
-20
lines changed

6 files changed

+74
-20
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_atomic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
// License. See LICENSE.TXT for details.
77
//
88
//===----------------------------------------------------------------------===//
9+
//
10+
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11+
//
12+
//===----------------------------------------------------------------------===//
913

1014
#ifndef SANITIZER_ATOMIC_H
1115
#define SANITIZER_ATOMIC_H

compiler-rt/lib/sanitizer_common/sanitizer_mutex.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
// License. See LICENSE.TXT for details.
77
//
88
//===----------------------------------------------------------------------===//
9+
//
10+
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11+
//
12+
//===----------------------------------------------------------------------===//
913

1014
#ifndef SANITIZER_MUTEX_H
1115
#define SANITIZER_MUTEX_H
@@ -15,6 +19,28 @@
1519

1620
namespace __sanitizer {
1721

22+
class SpinMutex {
23+
public:
24+
SpinMutex() {
25+
atomic_store(&state_, 0, memory_order_relaxed);
26+
}
27+
28+
void Lock() {
29+
while (atomic_exchange(&state_, 1, memory_order_acquire))
30+
proc_yield(10);
31+
}
32+
33+
void Unlock() {
34+
atomic_store(&state_, 0, memory_order_release);
35+
}
36+
37+
private:
38+
atomic_uint8_t state_;
39+
40+
SpinMutex(const SpinMutex&);
41+
void operator=(const SpinMutex&);
42+
};
43+
1844
template<typename MutexType>
1945
class GenericScopedLock {
2046
public:

compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ TEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {
124124
}
125125

126126
a.TestOnlyUnmap();
127+
(void)sink;
127128
}
128129

129130
void FailInAssertionOnOOM() {

compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
//
88
//===----------------------------------------------------------------------===//
99
//
10-
// This file is a part of ThreadSanitizer (TSan), a race detector.
10+
// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
1111
//
1212
//===----------------------------------------------------------------------===//
1313
#include "sanitizer_common/sanitizer_common.h"
1414
#include "gtest/gtest.h"
1515
#include <stdlib.h>
1616

17-
namespace __tsan {
17+
namespace __sanitizer {
1818

1919
TEST(Allocator, Basic) {
2020
char *p = (char*)InternalAlloc(10);
@@ -53,4 +53,4 @@ TEST(Allocator, Stress) {
5353
}
5454
}
5555

56-
} // namespace __tsan
56+
} // namespace __sanitizer

compiler-rt/lib/tsan/Makefile.old

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ LDFLAGS=-ldl -lpthread -pie
33
CXXFLAGS = -fPIE -g -Wall -Werror -DTSAN_DEBUG=$(DEBUG)
44
# Silence warnings that Clang produces for gtest code.
55
# Use -Wno-attributes so that gcc doesn't complain about unknown warning types.
6-
CXXFLAGS += -Wno-static-in-inline -Wno-attributes
6+
CXXFLAGS += -Wno-attributes
77
ifeq ($(DEBUG), 0)
88
CXXFLAGS += -O3
99
endif
1010
ifeq ($(CXX), clang++)
11-
CXXFLAGS+= -Wno-unused-private-field
11+
CXXFLAGS+= -Wno-unused-private-field -Wno-static-in-inline
1212
endif
1313

1414
LIBTSAN=rtl/libtsan.a

compiler-rt/lib/tsan/unit_tests/tsan_mutex_test.cc

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,23 @@
1313
#include "sanitizer_common/sanitizer_internal_defs.h"
1414
#include "sanitizer_common/sanitizer_atomic.h"
1515
#include "sanitizer_common/sanitizer_common.h"
16+
#include "sanitizer_common/sanitizer_mutex.h"
1617
#include "tsan_mutex.h"
1718
#include "gtest/gtest.h"
1819

1920
namespace __tsan {
2021

22+
template<typename MutexType>
2123
class TestData {
2224
public:
23-
TestData()
24-
: mtx_(MutexTypeAnnotations, StatMtxAnnotations) {
25+
TestData(MutexType *mtx)
26+
: mtx_(mtx) {
2527
for (int i = 0; i < kSize; i++)
2628
data_[i] = 0;
2729
}
2830

2931
void Write() {
30-
Lock l(&mtx_);
32+
Lock l(mtx_);
3133
T v0 = data_[0];
3234
for (int i = 0; i < kSize; i++) {
3335
CHECK_EQ(data_[i], v0);
@@ -36,17 +38,26 @@ class TestData {
3638
}
3739

3840
void Read() {
39-
ReadLock l(&mtx_);
41+
ReadLock l(mtx_);
4042
T v0 = data_[0];
4143
for (int i = 0; i < kSize; i++) {
4244
CHECK_EQ(data_[i], v0);
4345
}
4446
}
4547

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+
4656
private:
57+
typedef GenericScopedLock<MutexType> Lock;
4758
static const int kSize = 64;
4859
typedef u64 T;
49-
Mutex mtx_;
60+
MutexType *mtx_;
5061
char pad_[kCacheLineSize];
5162
T data_[kSize];
5263
};
@@ -59,43 +70,55 @@ const int kIters = 16*1024;
5970
const int kIters = 64*1024;
6071
#endif
6172

73+
template<typename MutexType>
6274
static void *write_mutex_thread(void *param) {
63-
TestData *data = (TestData *)param;
64-
TestData local;
75+
TestData<MutexType> *data = (TestData<MutexType>*)param;
6576
for (int i = 0; i < kIters; i++) {
6677
data->Write();
67-
local.Write();
78+
data->Backoff();
6879
}
6980
return 0;
7081
}
7182

83+
template<typename MutexType>
7284
static void *read_mutex_thread(void *param) {
73-
TestData *data = (TestData *)param;
74-
TestData local;
85+
TestData<MutexType> *data = (TestData<MutexType>*)param;
7586
for (int i = 0; i < kIters; i++) {
7687
if ((i % kWriteRate) == 0)
7788
data->Write();
7889
else
7990
data->Read();
80-
local.Write();
91+
data->Backoff();
8192
}
8293
return 0;
8394
}
8495

8596
TEST(Mutex, Write) {
86-
TestData data;
97+
Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);
98+
TestData<Mutex> data(&mtx);
8799
pthread_t threads[kThreads];
88100
for (int i = 0; i < kThreads; i++)
89-
pthread_create(&threads[i], 0, write_mutex_thread, &data);
101+
pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data);
90102
for (int i = 0; i < kThreads; i++)
91103
pthread_join(threads[i], 0);
92104
}
93105

94106
TEST(Mutex, ReadWrite) {
95-
TestData data;
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);
96119
pthread_t threads[kThreads];
97120
for (int i = 0; i < kThreads; i++)
98-
pthread_create(&threads[i], 0, read_mutex_thread, &data);
121+
pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data);
99122
for (int i = 0; i < kThreads; i++)
100123
pthread_join(threads[i], 0);
101124
}

0 commit comments

Comments
 (0)