Home | History | Annotate | Download | only in rtl
      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);
     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 
     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 initalization (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:
    117   MainThread()
    118     : ScopedThread(false, true) {
    119   }
    120 };
    121 
    122 #endif  // #ifndef TSAN_TEST_UTIL_H
    123