• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- 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 
17 void TestMutexBeforeInit();
18 
19 // A location of memory on which a race may be detected.
20 class MemLoc {
21  public:
22   explicit MemLoc(int offset_from_aligned = 0);
MemLoc(void * const real_addr)23   explicit MemLoc(void *const real_addr) : loc_(real_addr) { }
24   ~MemLoc();
loc()25   void *loc() const { return loc_; }
26  private:
27   void *const loc_;
28   MemLoc(const MemLoc&);
29   void operator = (const MemLoc&);
30 };
31 
32 class Mutex {
33  public:
34   enum Type {
35     Normal,
36     RW,
37 #ifndef __APPLE__
38     Spin
39 #else
40     Spin = Normal
41 #endif
42   };
43 
44   explicit Mutex(Type type = Normal);
45   ~Mutex();
46 
47   void Init();
48   void StaticInit();  // Emulates static initialization (tsan invisible).
49   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.
68 class 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 
123 class MainThread : public ScopedThread {
124  public:
MainThread()125   MainThread()
126     : ScopedThread(false, true) {
127   }
128 };
129 
130 #endif  // #ifndef TSAN_TEST_UTIL_H
131