• 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 { Normal, Spin, RW };
35 
36   explicit Mutex(Type type = Normal);
37   ~Mutex();
38 
39   void Init();
40   void StaticInit();  // Emulates static initialization (tsan invisible).
41   void Destroy();
42   void Lock();
43   bool TryLock();
44   void Unlock();
45   void ReadLock();
46   bool TryReadLock();
47   void ReadUnlock();
48 
49  private:
50   // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.
51   void *mtx_[128];
52   bool alive_;
53   const Type type_;
54 
55   Mutex(const Mutex&);
56   void operator = (const Mutex&);
57 };
58 
59 // A thread is started in CTOR and joined in DTOR.
60 class ScopedThread {
61  public:
62   explicit ScopedThread(bool detached = false, bool main = false);
63   ~ScopedThread();
64   void Detach();
65 
66   void Access(void *addr, bool is_write, int size, bool expect_race);
67   void Read(const MemLoc &ml, int size, bool expect_race = false) {
68     Access(ml.loc(), false, size, expect_race);
69   }
70   void Write(const MemLoc &ml, int size, bool expect_race = false) {
71     Access(ml.loc(), true, size, expect_race);
72   }
73   void Read1(const MemLoc &ml, bool expect_race = false) {
74     Read(ml, 1, expect_race); }
75   void Read2(const MemLoc &ml, bool expect_race = false) {
76     Read(ml, 2, expect_race); }
77   void Read4(const MemLoc &ml, bool expect_race = false) {
78     Read(ml, 4, expect_race); }
79   void Read8(const MemLoc &ml, bool expect_race = false) {
80     Read(ml, 8, expect_race); }
81   void Write1(const MemLoc &ml, bool expect_race = false) {
82     Write(ml, 1, expect_race); }
83   void Write2(const MemLoc &ml, bool expect_race = false) {
84     Write(ml, 2, expect_race); }
85   void Write4(const MemLoc &ml, bool expect_race = false) {
86     Write(ml, 4, expect_race); }
87   void Write8(const MemLoc &ml, bool expect_race = false) {
88     Write(ml, 8, expect_race); }
89 
90   void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val,
91                   bool expect_race = false);
92 
93   void Call(void(*pc)());
94   void Return();
95 
96   void Create(const Mutex &m);
97   void Destroy(const Mutex &m);
98   void Lock(const Mutex &m);
99   bool TryLock(const Mutex &m);
100   void Unlock(const Mutex &m);
101   void ReadLock(const Mutex &m);
102   bool TryReadLock(const Mutex &m);
103   void ReadUnlock(const Mutex &m);
104 
105   void Memcpy(void *dst, const void *src, int size, bool expect_race = false);
106   void Memset(void *dst, int val, int size, bool expect_race = false);
107 
108  private:
109   struct Impl;
110   Impl *impl_;
111   ScopedThread(const ScopedThread&);  // Not implemented.
112   void operator = (const ScopedThread&);  // Not implemented.
113 };
114 
115 class MainThread : public ScopedThread {
116  public:
MainThread()117   MainThread()
118     : ScopedThread(false, true) {
119   }
120 };
121 
122 #endif  // #ifndef TSAN_TEST_UTIL_H
123