1da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===-- tsan_test_util.h ----------------------------------------*- C++ -*-===// 2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// The LLVM Compiler Infrastructure 4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source 6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details. 7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===// 9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector. 11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// 12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// Test utils. 13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===// 14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#ifndef TSAN_TEST_UTIL_H 15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define TSAN_TEST_UTIL_H 16da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyvoid TestMutexBeforeInit(); 18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// A location of memory on which a race may be detected. 20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyclass MemLoc { 21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany public: 22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany explicit MemLoc(int offset_from_aligned = 0); 23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany explicit MemLoc(void *const real_addr) : loc_(real_addr) { } 24da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ~MemLoc(); 25da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void *loc() const { return loc_; } 26da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany private: 27da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void *const loc_; 28da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MemLoc(const MemLoc&); 29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void operator = (const MemLoc&); 30da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 31da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 32da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyclass Mutex { 33da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany public: 34da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany enum Type { Normal, Spin, RW }; 35da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 36da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany explicit Mutex(Type type = Normal); 37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ~Mutex(); 38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Init(); 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void StaticInit(); // Emulates static initialization (tsan invisible). 41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Destroy(); 42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Lock(); 43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool TryLock(); 44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Unlock(); 45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void ReadLock(); 46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool TryReadLock(); 47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void ReadUnlock(); 48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany private: 50da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever. 51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void *mtx_[128]; 52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool alive_; 53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany const Type type_; 54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Mutex(const Mutex&); 56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void operator = (const Mutex&); 57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// A thread is started in CTOR and joined in DTOR. 60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyclass ScopedThread { 61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany public: 62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany explicit ScopedThread(bool detached = false, bool main = false); 63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ~ScopedThread(); 64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Detach(); 65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Access(void *addr, bool is_write, int size, bool expect_race); 67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Read(const MemLoc &ml, int size, bool expect_race = false) { 68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Access(ml.loc(), false, size, expect_race); 69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 70da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Write(const MemLoc &ml, int size, bool expect_race = false) { 71da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Access(ml.loc(), true, size, expect_race); 72da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 73da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Read1(const MemLoc &ml, bool expect_race = false) { 74da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Read(ml, 1, expect_race); } 75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Read2(const MemLoc &ml, bool expect_race = false) { 76da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Read(ml, 2, expect_race); } 77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Read4(const MemLoc &ml, bool expect_race = false) { 78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Read(ml, 4, expect_race); } 79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Read8(const MemLoc &ml, bool expect_race = false) { 80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Read(ml, 8, expect_race); } 81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Write1(const MemLoc &ml, bool expect_race = false) { 82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Write(ml, 1, expect_race); } 83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Write2(const MemLoc &ml, bool expect_race = false) { 84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Write(ml, 2, expect_race); } 85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Write4(const MemLoc &ml, bool expect_race = false) { 86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Write(ml, 4, expect_race); } 87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Write8(const MemLoc &ml, bool expect_race = false) { 88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Write(ml, 8, expect_race); } 89da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 90da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val, 91da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool expect_race = false); 92da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 93da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Call(void(*pc)()); 94da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Return(); 95da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 96da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Create(const Mutex &m); 97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Destroy(const Mutex &m); 98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Lock(const Mutex &m); 99da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool TryLock(const Mutex &m); 100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Unlock(const Mutex &m); 101da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void ReadLock(const Mutex &m); 102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany bool TryReadLock(const Mutex &m); 103da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void ReadUnlock(const Mutex &m); 104da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 105da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Memcpy(void *dst, const void *src, int size, bool expect_race = false); 106da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void Memset(void *dst, int val, int size, bool expect_race = false); 107da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 108da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany private: 109da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany struct Impl; 110da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany Impl *impl_; 111da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany ScopedThread(const ScopedThread&); // Not implemented. 112da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany void operator = (const ScopedThread&); // Not implemented. 113da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 114da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 115da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanyclass MainThread : public ScopedThread { 116da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany public: 117da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany MainThread() 118da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany : ScopedThread(false, true) { 119da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany } 120da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}; 121da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany 122da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#endif // #ifndef TSAN_TEST_UTIL_H 123