blob: 31b1b188f6247b65db0bfad06e12999b37f7433d [file] [log] [blame]
Kostya Serebryanyda4edd82012-05-10 14:18:22 +00001//===-- tsan_test_util.h ----------------------------------------*- C++ -*-===//
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// Test utils.
13//===----------------------------------------------------------------------===//
14#ifndef TSAN_TEST_UTIL_H
15#define TSAN_TEST_UTIL_H
16
17void TestMutexBeforeInit();
18
19// A location of memory on which a race may be detected.
20class MemLoc {
21 public:
22 explicit MemLoc(int offset_from_aligned = 0);
23 explicit MemLoc(void *const real_addr) : loc_(real_addr) { }
24 ~MemLoc();
25 void *loc() const { return loc_; }
26 private:
27 void *const loc_;
28 MemLoc(const MemLoc&);
29 void operator = (const MemLoc&);
30};
31
32class Mutex {
33 public:
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080034 enum Type {
35 Normal,
36 RW,
37#ifndef __APPLE__
38 Spin
39#else
40 Spin = Normal
41#endif
42 };
Kostya Serebryanyda4edd82012-05-10 14:18:22 +000043
44 explicit Mutex(Type type = Normal);
45 ~Mutex();
46
47 void Init();
Stephen Hines2d1fdb22014-05-28 23:58:16 -070048 void StaticInit(); // Emulates static initialization (tsan invisible).
Kostya Serebryanyda4edd82012-05-10 14:18:22 +000049 void Destroy();
50 void Lock();
51 bool TryLock();
52 void Unlock();
53 void ReadLock();
54 bool TryReadLock();
55 void ReadUnlock();
56
57 private:
58 // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.
59 void *mtx_[128];
60 bool alive_;
61 const Type type_;
62
63 Mutex(const Mutex&);
64 void operator = (const Mutex&);
65};
66
67// A thread is started in CTOR and joined in DTOR.
68class ScopedThread {
69 public:
70 explicit ScopedThread(bool detached = false, bool main = false);
71 ~ScopedThread();
72 void Detach();
73
74 void Access(void *addr, bool is_write, int size, bool expect_race);
75 void Read(const MemLoc &ml, int size, bool expect_race = false) {
76 Access(ml.loc(), false, size, expect_race);
77 }
78 void Write(const MemLoc &ml, int size, bool expect_race = false) {
79 Access(ml.loc(), true, size, expect_race);
80 }
81 void Read1(const MemLoc &ml, bool expect_race = false) {
82 Read(ml, 1, expect_race); }
83 void Read2(const MemLoc &ml, bool expect_race = false) {
84 Read(ml, 2, expect_race); }
85 void Read4(const MemLoc &ml, bool expect_race = false) {
86 Read(ml, 4, expect_race); }
87 void Read8(const MemLoc &ml, bool expect_race = false) {
88 Read(ml, 8, expect_race); }
89 void Write1(const MemLoc &ml, bool expect_race = false) {
90 Write(ml, 1, expect_race); }
91 void Write2(const MemLoc &ml, bool expect_race = false) {
92 Write(ml, 2, expect_race); }
93 void Write4(const MemLoc &ml, bool expect_race = false) {
94 Write(ml, 4, expect_race); }
95 void Write8(const MemLoc &ml, bool expect_race = false) {
96 Write(ml, 8, expect_race); }
97
98 void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val,
99 bool expect_race = false);
100
101 void Call(void(*pc)());
102 void Return();
103
104 void Create(const Mutex &m);
105 void Destroy(const Mutex &m);
106 void Lock(const Mutex &m);
107 bool TryLock(const Mutex &m);
108 void Unlock(const Mutex &m);
109 void ReadLock(const Mutex &m);
110 bool TryReadLock(const Mutex &m);
111 void ReadUnlock(const Mutex &m);
112
113 void Memcpy(void *dst, const void *src, int size, bool expect_race = false);
114 void Memset(void *dst, int val, int size, bool expect_race = false);
115
116 private:
117 struct Impl;
118 Impl *impl_;
119 ScopedThread(const ScopedThread&); // Not implemented.
120 void operator = (const ScopedThread&); // Not implemented.
121};
122
123class MainThread : public ScopedThread {
124 public:
125 MainThread()
126 : ScopedThread(false, true) {
127 }
128};
129
130#endif // #ifndef TSAN_TEST_UTIL_H