1 //===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_atomic.h"
15 #include "sanitizer_common/sanitizer_common.h"
16 #include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
17 #include "tsan_clock.h"
18 #include "tsan_defs.h"
19 #include "tsan_mutex.h"
26 // Initialized the object in "static mode",
27 // in this mode it never calls malloc/free but uses the provided buffer.
28 StackTrace(uptr
*buf
, uptr cnt
);
32 void Init(const uptr
*pcs
, uptr cnt
);
33 void ObtainCurrent(ThreadState
*thr
, uptr toppc
);
36 uptr
Get(uptr i
) const;
37 const uptr
*Begin() const;
38 void CopyFrom(const StackTrace
& other
);
45 StackTrace(const StackTrace
&);
46 void operator = (const StackTrace
&);
50 explicit SyncVar(uptr addr
, u64 uid
);
52 static const int kInvalidTid
= -1;
56 const u64 uid
; // Globally unique id.
57 u32 creation_stack_id
;
58 int owner_tid
; // Set only by exclusive owners.
65 SyncVar
*next
; // In SyncTab hashtable.
67 SyncClock read_clock
; // Used for rw mutexes only.
68 // The clock is placed last, so that it is situated on a different cache line
69 // with the mtx. This reduces contention for hot sync objects.
73 // 47 lsb is addr, then 14 bits is low part of uid, then 3 zero bits.
74 return GetLsb((u64
)addr
| (uid
<< 47), 61);
76 bool CheckId(u64 uid
) const {
77 CHECK_EQ(uid
, GetLsb(uid
, 14));
78 return GetLsb(this->uid
, 14) == uid
;
80 static uptr
SplitId(u64 id
, u64
*uid
) {
82 return (uptr
)GetLsb(id
, 47);
91 SyncVar
* GetOrCreateAndLock(ThreadState
*thr
, uptr pc
,
92 uptr addr
, bool write_lock
);
93 SyncVar
* GetIfExistsAndLock(uptr addr
, bool write_lock
);
95 // If the SyncVar does not exist, returns 0.
96 SyncVar
* GetAndRemove(ThreadState
*thr
, uptr pc
, uptr addr
);
98 SyncVar
* Create(ThreadState
*thr
, uptr pc
, uptr addr
);
104 char pad
[kCacheLineSize
- sizeof(Mutex
) - sizeof(SyncVar
*)]; // NOLINT
108 // FIXME: Implement something more sane.
109 static const int kPartCount
= 1009;
110 Part tab_
[kPartCount
];
111 atomic_uint64_t uid_gen_
;
113 int PartIdx(uptr addr
);
115 SyncVar
* GetAndLock(ThreadState
*thr
, uptr pc
,
116 uptr addr
, bool write_lock
, bool create
);
118 SyncTab(const SyncTab
&); // Not implemented.
119 void operator = (const SyncTab
&); // Not implemented.
122 } // namespace __tsan
124 #endif // TSAN_SYNC_H