• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- tsan_clock.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 //===----------------------------------------------------------------------===//
13 #ifndef TSAN_CLOCK_H
14 #define TSAN_CLOCK_H
15 
16 #include "tsan_defs.h"
17 #include "tsan_vector.h"
18 
19 namespace __tsan {
20 
21 struct ClockElem {
22   u64 epoch  : kClkBits;
23   u64 reused : 64 - kClkBits;
24 };
25 
26 // The clock that lives in sync variables (mutexes, atomics, etc).
27 class SyncClock {
28  public:
29   SyncClock();
30 
size()31   uptr size() const {
32     return clk_.Size();
33   }
34 
get(unsigned tid)35   u64 get(unsigned tid) const {
36     DCHECK_LT(tid, clk_.Size());
37     return clk_[tid].epoch;
38   }
39 
40   void Reset();
41   void Zero();
42 
43   void DebugDump(int(*printf)(const char *s, ...));
44 
45  private:
46   unsigned release_store_tid_;
47   unsigned release_store_reused_;
48   static const uptr kDirtyTids = 2;
49   unsigned dirty_tids_[kDirtyTids];
50   mutable Vector<ClockElem> clk_;
51   friend struct ThreadClock;
52 };
53 
54 // The clock that lives in threads.
55 struct ThreadClock {
56  public:
57   explicit ThreadClock(unsigned tid, unsigned reused = 0);
58 
getThreadClock59   u64 get(unsigned tid) const {
60     DCHECK_LT(tid, kMaxTidInClock);
61     return clk_[tid].epoch;
62   }
63 
64   void set(unsigned tid, u64 v);
65 
setThreadClock66   void set(u64 v) {
67     DCHECK_GE(v, clk_[tid_].epoch);
68     clk_[tid_].epoch = v;
69   }
70 
tickThreadClock71   void tick() {
72     clk_[tid_].epoch++;
73   }
74 
sizeThreadClock75   uptr size() const {
76     return nclk_;
77   }
78 
79   void acquire(const SyncClock *src);
80   void release(SyncClock *dst) const;
81   void acq_rel(SyncClock *dst);
82   void ReleaseStore(SyncClock *dst) const;
83 
84   void DebugReset();
85   void DebugDump(int(*printf)(const char *s, ...));
86 
87  private:
88   static const uptr kDirtyTids = SyncClock::kDirtyTids;
89   const unsigned tid_;
90   const unsigned reused_;
91   u64 last_acquire_;
92   uptr nclk_;
93   ClockElem clk_[kMaxTidInClock];
94 
95   bool IsAlreadyAcquired(const SyncClock *src) const;
96   void UpdateCurrentThread(SyncClock *dst) const;
97 };
98 
99 }  // namespace __tsan
100 
101 #endif  // TSAN_CLOCK_H
102