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