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 {
     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:
    125   MainThread()
    126     : ScopedThread(false, true) {
    127   }
    128 };
    129 
    130 #endif  // #ifndef TSAN_TEST_UTIL_H
    131