xref: /aosp_15_r20/external/compiler-rt/lib/tsan/rtl/tsan_sync.h (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot //===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot //                     The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of ThreadSanitizer (TSan), a race detector.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
13*7c3d14c8STreehugger Robot #ifndef TSAN_SYNC_H
14*7c3d14c8STreehugger Robot #define TSAN_SYNC_H
15*7c3d14c8STreehugger Robot 
16*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_atomic.h"
17*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_common.h"
18*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
19*7c3d14c8STreehugger Robot #include "tsan_defs.h"
20*7c3d14c8STreehugger Robot #include "tsan_clock.h"
21*7c3d14c8STreehugger Robot #include "tsan_mutex.h"
22*7c3d14c8STreehugger Robot #include "tsan_dense_alloc.h"
23*7c3d14c8STreehugger Robot 
24*7c3d14c8STreehugger Robot namespace __tsan {
25*7c3d14c8STreehugger Robot 
26*7c3d14c8STreehugger Robot struct SyncVar {
27*7c3d14c8STreehugger Robot   SyncVar();
28*7c3d14c8STreehugger Robot 
29*7c3d14c8STreehugger Robot   static const int kInvalidTid = -1;
30*7c3d14c8STreehugger Robot 
31*7c3d14c8STreehugger Robot   uptr addr;  // overwritten by DenseSlabAlloc freelist
32*7c3d14c8STreehugger Robot   Mutex mtx;
33*7c3d14c8STreehugger Robot   u64 uid;  // Globally unique id.
34*7c3d14c8STreehugger Robot   u32 creation_stack_id;
35*7c3d14c8STreehugger Robot   int owner_tid;  // Set only by exclusive owners.
36*7c3d14c8STreehugger Robot   u64 last_lock;
37*7c3d14c8STreehugger Robot   int recursion;
38*7c3d14c8STreehugger Robot   bool is_rw;
39*7c3d14c8STreehugger Robot   bool is_recursive;
40*7c3d14c8STreehugger Robot   bool is_broken;
41*7c3d14c8STreehugger Robot   bool is_linker_init;
42*7c3d14c8STreehugger Robot   u32 next;  // in MetaMap
43*7c3d14c8STreehugger Robot   DDMutex dd;
44*7c3d14c8STreehugger Robot   SyncClock read_clock;  // Used for rw mutexes only.
45*7c3d14c8STreehugger Robot   // The clock is placed last, so that it is situated on a different cache line
46*7c3d14c8STreehugger Robot   // with the mtx. This reduces contention for hot sync objects.
47*7c3d14c8STreehugger Robot   SyncClock clock;
48*7c3d14c8STreehugger Robot 
49*7c3d14c8STreehugger Robot   void Init(ThreadState *thr, uptr pc, uptr addr, u64 uid);
50*7c3d14c8STreehugger Robot   void Reset(Processor *proc);
51*7c3d14c8STreehugger Robot 
GetIdSyncVar52*7c3d14c8STreehugger Robot   u64 GetId() const {
53*7c3d14c8STreehugger Robot     // 47 lsb is addr, then 14 bits is low part of uid, then 3 zero bits.
54*7c3d14c8STreehugger Robot     return GetLsb((u64)addr | (uid << 47), 61);
55*7c3d14c8STreehugger Robot   }
CheckIdSyncVar56*7c3d14c8STreehugger Robot   bool CheckId(u64 uid) const {
57*7c3d14c8STreehugger Robot     CHECK_EQ(uid, GetLsb(uid, 14));
58*7c3d14c8STreehugger Robot     return GetLsb(this->uid, 14) == uid;
59*7c3d14c8STreehugger Robot   }
SplitIdSyncVar60*7c3d14c8STreehugger Robot   static uptr SplitId(u64 id, u64 *uid) {
61*7c3d14c8STreehugger Robot     *uid = id >> 47;
62*7c3d14c8STreehugger Robot     return (uptr)GetLsb(id, 47);
63*7c3d14c8STreehugger Robot   }
64*7c3d14c8STreehugger Robot };
65*7c3d14c8STreehugger Robot 
66*7c3d14c8STreehugger Robot /* MetaMap allows to map arbitrary user pointers onto various descriptors.
67*7c3d14c8STreehugger Robot    Currently it maps pointers to heap block descriptors and sync var descs.
68*7c3d14c8STreehugger Robot    It uses 1/2 direct shadow, see tsan_platform.h.
69*7c3d14c8STreehugger Robot */
70*7c3d14c8STreehugger Robot class MetaMap {
71*7c3d14c8STreehugger Robot  public:
72*7c3d14c8STreehugger Robot   MetaMap();
73*7c3d14c8STreehugger Robot 
74*7c3d14c8STreehugger Robot   void AllocBlock(ThreadState *thr, uptr pc, uptr p, uptr sz);
75*7c3d14c8STreehugger Robot   uptr FreeBlock(Processor *proc, uptr p);
76*7c3d14c8STreehugger Robot   bool FreeRange(Processor *proc, uptr p, uptr sz);
77*7c3d14c8STreehugger Robot   void ResetRange(Processor *proc, uptr p, uptr sz);
78*7c3d14c8STreehugger Robot   MBlock* GetBlock(uptr p);
79*7c3d14c8STreehugger Robot 
80*7c3d14c8STreehugger Robot   SyncVar* GetOrCreateAndLock(ThreadState *thr, uptr pc,
81*7c3d14c8STreehugger Robot                               uptr addr, bool write_lock);
82*7c3d14c8STreehugger Robot   SyncVar* GetIfExistsAndLock(uptr addr, bool write_lock);
83*7c3d14c8STreehugger Robot 
84*7c3d14c8STreehugger Robot   void MoveMemory(uptr src, uptr dst, uptr sz);
85*7c3d14c8STreehugger Robot 
86*7c3d14c8STreehugger Robot   void OnProcIdle(Processor *proc);
87*7c3d14c8STreehugger Robot 
88*7c3d14c8STreehugger Robot  private:
89*7c3d14c8STreehugger Robot   static const u32 kFlagMask  = 3u << 30;
90*7c3d14c8STreehugger Robot   static const u32 kFlagBlock = 1u << 30;
91*7c3d14c8STreehugger Robot   static const u32 kFlagSync  = 2u << 30;
92*7c3d14c8STreehugger Robot   typedef DenseSlabAlloc<MBlock, 1<<16, 1<<12> BlockAlloc;
93*7c3d14c8STreehugger Robot   typedef DenseSlabAlloc<SyncVar, 1<<16, 1<<10> SyncAlloc;
94*7c3d14c8STreehugger Robot   BlockAlloc block_alloc_;
95*7c3d14c8STreehugger Robot   SyncAlloc sync_alloc_;
96*7c3d14c8STreehugger Robot   atomic_uint64_t uid_gen_;
97*7c3d14c8STreehugger Robot 
98*7c3d14c8STreehugger Robot   SyncVar* GetAndLock(ThreadState *thr, uptr pc, uptr addr, bool write_lock,
99*7c3d14c8STreehugger Robot                       bool create);
100*7c3d14c8STreehugger Robot };
101*7c3d14c8STreehugger Robot 
102*7c3d14c8STreehugger Robot }  // namespace __tsan
103*7c3d14c8STreehugger Robot 
104*7c3d14c8STreehugger Robot #endif  // TSAN_SYNC_H
105