blob: a57a0e4f791e7b09e86a730f16fd83de3a177fa8 [file] [log] [blame]
Kostya Serebryany4ad375f2012-05-10 13:48:04 +00001//===-- 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
19namespace __tsan {
20
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000021const u64 kClkMask = (1ULL << kClkBits) - 1;
22
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000023// The clock that lives in sync variables (mutexes, atomics, etc).
24class SyncClock {
25 public:
26 SyncClock();
27
28 uptr size() const {
29 return clk_.Size();
30 }
31
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000032 u64 get(unsigned tid) const {
33 DCHECK_LT(tid, clk_.Size());
34 return clk_[tid] & kClkMask;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000035 }
36
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000037 void Reset();
38
39 void DebugDump(int(*printf)(const char *s, ...));
40
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000041 private:
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000042 u64 release_seq_;
43 unsigned release_store_tid_;
44 static const uptr kDirtyTids = 2;
45 unsigned dirty_tids_[kDirtyTids];
46 mutable Vector<u64> clk_;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000047 friend struct ThreadClock;
48};
49
50// The clock that lives in threads.
51struct ThreadClock {
52 public:
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000053 explicit ThreadClock(unsigned tid);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000054
Kostya Serebryany07c48052012-05-11 14:42:24 +000055 u64 get(unsigned tid) const {
Dmitry Vyukov302cebb2012-05-22 18:07:45 +000056 DCHECK_LT(tid, kMaxTidInClock);
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000057 DCHECK_EQ(clk_[tid], clk_[tid] & kClkMask);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000058 return clk_[tid];
59 }
60
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000061 void set(unsigned tid, u64 v);
62
63 void set(u64 v) {
64 DCHECK_GE(v, clk_[tid_]);
65 clk_[tid_] = v;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000066 }
67
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000068 void tick() {
69 clk_[tid_]++;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000070 }
71
72 uptr size() const {
73 return nclk_;
74 }
75
76 void acquire(const SyncClock *src);
77 void release(SyncClock *dst) const;
78 void acq_rel(SyncClock *dst);
Dmitry Vyukov904d3f92012-07-28 15:27:41 +000079 void ReleaseStore(SyncClock *dst) const;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000080
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000081 void DebugDump(int(*printf)(const char *s, ...));
82
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000083 private:
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000084 static const uptr kDirtyTids = SyncClock::kDirtyTids;
85 const unsigned tid_;
86 u64 last_acquire_;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000087 uptr nclk_;
Dmitry Vyukovfee5b7d2012-05-17 14:17:51 +000088 u64 clk_[kMaxTidInClock];
Dmitry Vyukovd23118c2014-03-24 18:54:20 +000089
90 bool IsAlreadyAcquired(const SyncClock *src) const;
91 void UpdateCurrentThread(SyncClock *dst) const;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000092};
93
94} // namespace __tsan
95
96#endif // TSAN_CLOCK_H