• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- tsan_sync.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_SYNC_H
14 #define TSAN_SYNC_H
15 
16 #include "sanitizer_common/sanitizer_atomic.h"
17 #include "sanitizer_common/sanitizer_common.h"
18 #include "tsan_clock.h"
19 #include "tsan_defs.h"
20 #include "tsan_mutex.h"
21 
22 namespace __tsan {
23 
24 class SlabCache;
25 
26 class StackTrace {
27  public:
28   StackTrace();
29   // Initialized the object in "static mode",
30   // in this mode it never calls malloc/free but uses the provided buffer.
31   StackTrace(uptr *buf, uptr cnt);
32   ~StackTrace();
33   void Reset();
34 
35   void Init(const uptr *pcs, uptr cnt);
36   void ObtainCurrent(ThreadState *thr, uptr toppc);
37   bool IsEmpty() const;
38   uptr Size() const;
39   uptr Get(uptr i) const;
40   const uptr *Begin() const;
41   void CopyFrom(const StackTrace& other);
42 
43  private:
44   uptr n_;
45   uptr *s_;
46   const uptr c_;
47 
48   StackTrace(const StackTrace&);
49   void operator = (const StackTrace&);
50 };
51 
52 struct SyncVar {
53   explicit SyncVar(uptr addr);
54 
55   static const int kInvalidTid = -1;
56 
57   Mutex mtx;
58   const uptr addr;
59   SyncClock clock;
60   SyncClock read_clock;  // Used for rw mutexes only.
61   StackTrace creation_stack;
62   int owner_tid;  // Set only by exclusive owners.
63   u64 last_lock;
64   int recursion;
65   bool is_rw;
66   bool is_recursive;
67   bool is_broken;
68   bool is_linker_init;
69   SyncVar *next;  // In SyncTab hashtable.
70 
71   uptr GetMemoryConsumption();
72 };
73 
74 class SyncTab {
75  public:
76   SyncTab();
77   ~SyncTab();
78 
79   // If the SyncVar does not exist yet, it is created.
80   SyncVar* GetAndLock(ThreadState *thr, uptr pc,
81                       uptr addr, bool write_lock);
82 
83   // If the SyncVar does not exist, returns 0.
84   SyncVar* GetAndRemove(ThreadState *thr, uptr pc, uptr addr);
85 
86   uptr GetMemoryConsumption(uptr *nsync);
87 
88  private:
89   struct Part {
90     Mutex mtx;
91     SyncVar *val;
92     char pad[kCacheLineSize - sizeof(Mutex) - sizeof(SyncVar*)];  // NOLINT
93     Part();
94   };
95 
96   // FIXME: Implement something more sane.
97   static const int kPartCount = 1009;
98   Part tab_[kPartCount];
99 
100   int PartIdx(uptr addr);
101 
102   SyncTab(const SyncTab&);  // Not implemented.
103   void operator = (const SyncTab&);  // Not implemented.
104 };
105 
106 }  // namespace __tsan
107 
108 #endif  // TSAN_SYNC_H
109