annotate libsanitizer/tsan/tsan_sync.h @ 143:76e1cf5455ef

add cbc_gc test
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 19:24:05 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 //===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
kono
parents:
diff changeset
2 //
kono
parents:
diff changeset
3 // This file is distributed under the University of Illinois Open Source
kono
parents:
diff changeset
4 // License. See LICENSE.TXT for details.
kono
parents:
diff changeset
5 //
kono
parents:
diff changeset
6 //===----------------------------------------------------------------------===//
kono
parents:
diff changeset
7 //
kono
parents:
diff changeset
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
kono
parents:
diff changeset
9 //
kono
parents:
diff changeset
10 //===----------------------------------------------------------------------===//
kono
parents:
diff changeset
11 #ifndef TSAN_SYNC_H
kono
parents:
diff changeset
12 #define TSAN_SYNC_H
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 #include "sanitizer_common/sanitizer_atomic.h"
kono
parents:
diff changeset
15 #include "sanitizer_common/sanitizer_common.h"
kono
parents:
diff changeset
16 #include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
kono
parents:
diff changeset
17 #include "tsan_defs.h"
kono
parents:
diff changeset
18 #include "tsan_clock.h"
kono
parents:
diff changeset
19 #include "tsan_mutex.h"
kono
parents:
diff changeset
20 #include "tsan_dense_alloc.h"
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 namespace __tsan {
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 // These need to match __tsan_mutex_* flags defined in tsan_interface.h.
kono
parents:
diff changeset
25 // See documentation there as well.
kono
parents:
diff changeset
26 enum MutexFlags {
kono
parents:
diff changeset
27 MutexFlagLinkerInit = 1 << 0, // __tsan_mutex_linker_init
kono
parents:
diff changeset
28 MutexFlagWriteReentrant = 1 << 1, // __tsan_mutex_write_reentrant
kono
parents:
diff changeset
29 MutexFlagReadReentrant = 1 << 2, // __tsan_mutex_read_reentrant
kono
parents:
diff changeset
30 MutexFlagReadLock = 1 << 3, // __tsan_mutex_read_lock
kono
parents:
diff changeset
31 MutexFlagTryLock = 1 << 4, // __tsan_mutex_try_lock
kono
parents:
diff changeset
32 MutexFlagTryLockFailed = 1 << 5, // __tsan_mutex_try_lock_failed
kono
parents:
diff changeset
33 MutexFlagRecursiveLock = 1 << 6, // __tsan_mutex_recursive_lock
kono
parents:
diff changeset
34 MutexFlagRecursiveUnlock = 1 << 7, // __tsan_mutex_recursive_unlock
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 // The following flags are runtime private.
kono
parents:
diff changeset
37 // Mutex API misuse was detected, so don't report any more.
kono
parents:
diff changeset
38 MutexFlagBroken = 1 << 30,
kono
parents:
diff changeset
39 // We did not intercept pre lock event, so handle it on post lock.
kono
parents:
diff changeset
40 MutexFlagDoPreLockOnPostLock = 1 << 29,
kono
parents:
diff changeset
41 // Must list all mutex creation flags.
kono
parents:
diff changeset
42 MutexCreationFlagMask = MutexFlagLinkerInit |
kono
parents:
diff changeset
43 MutexFlagWriteReentrant |
kono
parents:
diff changeset
44 MutexFlagReadReentrant,
kono
parents:
diff changeset
45 };
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 struct SyncVar {
kono
parents:
diff changeset
48 SyncVar();
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 static const int kInvalidTid = -1;
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 uptr addr; // overwritten by DenseSlabAlloc freelist
kono
parents:
diff changeset
53 Mutex mtx;
kono
parents:
diff changeset
54 u64 uid; // Globally unique id.
kono
parents:
diff changeset
55 u32 creation_stack_id;
kono
parents:
diff changeset
56 int owner_tid; // Set only by exclusive owners.
kono
parents:
diff changeset
57 u64 last_lock;
kono
parents:
diff changeset
58 int recursion;
kono
parents:
diff changeset
59 atomic_uint32_t flags;
kono
parents:
diff changeset
60 u32 next; // in MetaMap
kono
parents:
diff changeset
61 DDMutex dd;
kono
parents:
diff changeset
62 SyncClock read_clock; // Used for rw mutexes only.
kono
parents:
diff changeset
63 // The clock is placed last, so that it is situated on a different cache line
kono
parents:
diff changeset
64 // with the mtx. This reduces contention for hot sync objects.
kono
parents:
diff changeset
65 SyncClock clock;
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 void Init(ThreadState *thr, uptr pc, uptr addr, u64 uid);
kono
parents:
diff changeset
68 void Reset(Processor *proc);
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 u64 GetId() const {
kono
parents:
diff changeset
71 // 48 lsb is addr, then 14 bits is low part of uid, then 2 zero bits.
kono
parents:
diff changeset
72 return GetLsb((u64)addr | (uid << 48), 60);
kono
parents:
diff changeset
73 }
kono
parents:
diff changeset
74 bool CheckId(u64 uid) const {
kono
parents:
diff changeset
75 CHECK_EQ(uid, GetLsb(uid, 14));
kono
parents:
diff changeset
76 return GetLsb(this->uid, 14) == uid;
kono
parents:
diff changeset
77 }
kono
parents:
diff changeset
78 static uptr SplitId(u64 id, u64 *uid) {
kono
parents:
diff changeset
79 *uid = id >> 48;
kono
parents:
diff changeset
80 return (uptr)GetLsb(id, 48);
kono
parents:
diff changeset
81 }
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 bool IsFlagSet(u32 f) const {
kono
parents:
diff changeset
84 return atomic_load_relaxed(&flags) & f;
kono
parents:
diff changeset
85 }
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 void SetFlags(u32 f) {
kono
parents:
diff changeset
88 atomic_store_relaxed(&flags, atomic_load_relaxed(&flags) | f);
kono
parents:
diff changeset
89 }
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 void UpdateFlags(u32 flagz) {
kono
parents:
diff changeset
92 // Filter out operation flags.
kono
parents:
diff changeset
93 if (!(flagz & MutexCreationFlagMask))
kono
parents:
diff changeset
94 return;
kono
parents:
diff changeset
95 u32 current = atomic_load_relaxed(&flags);
kono
parents:
diff changeset
96 if (current & MutexCreationFlagMask)
kono
parents:
diff changeset
97 return;
kono
parents:
diff changeset
98 // Note: this can be called from MutexPostReadLock which holds only read
kono
parents:
diff changeset
99 // lock on the SyncVar.
kono
parents:
diff changeset
100 atomic_store_relaxed(&flags, current | (flagz & MutexCreationFlagMask));
kono
parents:
diff changeset
101 }
kono
parents:
diff changeset
102 };
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 /* MetaMap allows to map arbitrary user pointers onto various descriptors.
kono
parents:
diff changeset
105 Currently it maps pointers to heap block descriptors and sync var descs.
kono
parents:
diff changeset
106 It uses 1/2 direct shadow, see tsan_platform.h.
kono
parents:
diff changeset
107 */
kono
parents:
diff changeset
108 class MetaMap {
kono
parents:
diff changeset
109 public:
kono
parents:
diff changeset
110 MetaMap();
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 void AllocBlock(ThreadState *thr, uptr pc, uptr p, uptr sz);
kono
parents:
diff changeset
113 uptr FreeBlock(Processor *proc, uptr p);
kono
parents:
diff changeset
114 bool FreeRange(Processor *proc, uptr p, uptr sz);
kono
parents:
diff changeset
115 void ResetRange(Processor *proc, uptr p, uptr sz);
kono
parents:
diff changeset
116 MBlock* GetBlock(uptr p);
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 SyncVar* GetOrCreateAndLock(ThreadState *thr, uptr pc,
kono
parents:
diff changeset
119 uptr addr, bool write_lock);
kono
parents:
diff changeset
120 SyncVar* GetIfExistsAndLock(uptr addr, bool write_lock);
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 void MoveMemory(uptr src, uptr dst, uptr sz);
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 void OnProcIdle(Processor *proc);
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 private:
kono
parents:
diff changeset
127 static const u32 kFlagMask = 3u << 30;
kono
parents:
diff changeset
128 static const u32 kFlagBlock = 1u << 30;
kono
parents:
diff changeset
129 static const u32 kFlagSync = 2u << 30;
kono
parents:
diff changeset
130 typedef DenseSlabAlloc<MBlock, 1<<16, 1<<12> BlockAlloc;
kono
parents:
diff changeset
131 typedef DenseSlabAlloc<SyncVar, 1<<16, 1<<10> SyncAlloc;
kono
parents:
diff changeset
132 BlockAlloc block_alloc_;
kono
parents:
diff changeset
133 SyncAlloc sync_alloc_;
kono
parents:
diff changeset
134 atomic_uint64_t uid_gen_;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 SyncVar* GetAndLock(ThreadState *thr, uptr pc, uptr addr, bool write_lock,
kono
parents:
diff changeset
137 bool create);
kono
parents:
diff changeset
138 };
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 } // namespace __tsan
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 #endif // TSAN_SYNC_H