xref: /netbsd-src/external/gpl3/gcc/dist/libsanitizer/tsan/tsan_interface_ann.cpp (revision ff6d591ca308ed13e9c5ae142cf113a246c2cdc6)
1*ff6d591cSmrg //===-- tsan_interface_ann.cpp --------------------------------------------===//
2*ff6d591cSmrg //
3*ff6d591cSmrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*ff6d591cSmrg // See https://llvm.org/LICENSE.txt for license information.
5*ff6d591cSmrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*ff6d591cSmrg //
7*ff6d591cSmrg //===----------------------------------------------------------------------===//
8*ff6d591cSmrg //
9*ff6d591cSmrg // This file is a part of ThreadSanitizer (TSan), a race detector.
10*ff6d591cSmrg //
11*ff6d591cSmrg //===----------------------------------------------------------------------===//
12*ff6d591cSmrg #include "sanitizer_common/sanitizer_libc.h"
13*ff6d591cSmrg #include "sanitizer_common/sanitizer_internal_defs.h"
14*ff6d591cSmrg #include "sanitizer_common/sanitizer_placement_new.h"
15*ff6d591cSmrg #include "sanitizer_common/sanitizer_stacktrace.h"
16*ff6d591cSmrg #include "sanitizer_common/sanitizer_vector.h"
17*ff6d591cSmrg #include "tsan_interface_ann.h"
18*ff6d591cSmrg #include "tsan_report.h"
19*ff6d591cSmrg #include "tsan_rtl.h"
20*ff6d591cSmrg #include "tsan_mman.h"
21*ff6d591cSmrg #include "tsan_flags.h"
22*ff6d591cSmrg #include "tsan_platform.h"
23*ff6d591cSmrg 
24*ff6d591cSmrg #define CALLERPC ((uptr)__builtin_return_address(0))
25*ff6d591cSmrg 
26*ff6d591cSmrg using namespace __tsan;
27*ff6d591cSmrg 
28*ff6d591cSmrg namespace __tsan {
29*ff6d591cSmrg 
30*ff6d591cSmrg class ScopedAnnotation {
31*ff6d591cSmrg  public:
ScopedAnnotation(ThreadState * thr,const char * aname,uptr pc)32*ff6d591cSmrg   ScopedAnnotation(ThreadState *thr, const char *aname, uptr pc)
33*ff6d591cSmrg       : thr_(thr) {
34*ff6d591cSmrg     FuncEntry(thr_, pc);
35*ff6d591cSmrg     DPrintf("#%d: annotation %s()\n", thr_->tid, aname);
36*ff6d591cSmrg   }
37*ff6d591cSmrg 
~ScopedAnnotation()38*ff6d591cSmrg   ~ScopedAnnotation() {
39*ff6d591cSmrg     FuncExit(thr_);
40*ff6d591cSmrg     CheckedMutex::CheckNoLocks();
41*ff6d591cSmrg   }
42*ff6d591cSmrg  private:
43*ff6d591cSmrg   ThreadState *const thr_;
44*ff6d591cSmrg };
45*ff6d591cSmrg 
46*ff6d591cSmrg #define SCOPED_ANNOTATION_RET(typ, ret)                     \
47*ff6d591cSmrg   if (!flags()->enable_annotations)                         \
48*ff6d591cSmrg     return ret;                                             \
49*ff6d591cSmrg   ThreadState *thr = cur_thread();                          \
50*ff6d591cSmrg   const uptr caller_pc = (uptr)__builtin_return_address(0); \
51*ff6d591cSmrg   ScopedAnnotation sa(thr, __func__, caller_pc);            \
52*ff6d591cSmrg   const uptr pc = StackTrace::GetCurrentPc();               \
53*ff6d591cSmrg   (void)pc;
54*ff6d591cSmrg 
55*ff6d591cSmrg #define SCOPED_ANNOTATION(typ) SCOPED_ANNOTATION_RET(typ, )
56*ff6d591cSmrg 
57*ff6d591cSmrg static const int kMaxDescLen = 128;
58*ff6d591cSmrg 
59*ff6d591cSmrg struct ExpectRace {
60*ff6d591cSmrg   ExpectRace *next;
61*ff6d591cSmrg   ExpectRace *prev;
62*ff6d591cSmrg   atomic_uintptr_t hitcount;
63*ff6d591cSmrg   atomic_uintptr_t addcount;
64*ff6d591cSmrg   uptr addr;
65*ff6d591cSmrg   uptr size;
66*ff6d591cSmrg   char *file;
67*ff6d591cSmrg   int line;
68*ff6d591cSmrg   char desc[kMaxDescLen];
69*ff6d591cSmrg };
70*ff6d591cSmrg 
71*ff6d591cSmrg struct DynamicAnnContext {
72*ff6d591cSmrg   Mutex mtx;
73*ff6d591cSmrg   ExpectRace benign;
74*ff6d591cSmrg 
DynamicAnnContext__tsan::DynamicAnnContext75*ff6d591cSmrg   DynamicAnnContext() : mtx(MutexTypeAnnotations) {}
76*ff6d591cSmrg };
77*ff6d591cSmrg 
78*ff6d591cSmrg static DynamicAnnContext *dyn_ann_ctx;
79*ff6d591cSmrg static char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);
80*ff6d591cSmrg 
AddExpectRace(ExpectRace * list,char * f,int l,uptr addr,uptr size,char * desc)81*ff6d591cSmrg static void AddExpectRace(ExpectRace *list,
82*ff6d591cSmrg     char *f, int l, uptr addr, uptr size, char *desc) {
83*ff6d591cSmrg   ExpectRace *race = list->next;
84*ff6d591cSmrg   for (; race != list; race = race->next) {
85*ff6d591cSmrg     if (race->addr == addr && race->size == size) {
86*ff6d591cSmrg       atomic_store_relaxed(&race->addcount,
87*ff6d591cSmrg           atomic_load_relaxed(&race->addcount) + 1);
88*ff6d591cSmrg       return;
89*ff6d591cSmrg     }
90*ff6d591cSmrg   }
91*ff6d591cSmrg   race = static_cast<ExpectRace *>(Alloc(sizeof(ExpectRace)));
92*ff6d591cSmrg   race->addr = addr;
93*ff6d591cSmrg   race->size = size;
94*ff6d591cSmrg   race->file = f;
95*ff6d591cSmrg   race->line = l;
96*ff6d591cSmrg   race->desc[0] = 0;
97*ff6d591cSmrg   atomic_store_relaxed(&race->hitcount, 0);
98*ff6d591cSmrg   atomic_store_relaxed(&race->addcount, 1);
99*ff6d591cSmrg   if (desc) {
100*ff6d591cSmrg     int i = 0;
101*ff6d591cSmrg     for (; i < kMaxDescLen - 1 && desc[i]; i++)
102*ff6d591cSmrg       race->desc[i] = desc[i];
103*ff6d591cSmrg     race->desc[i] = 0;
104*ff6d591cSmrg   }
105*ff6d591cSmrg   race->prev = list;
106*ff6d591cSmrg   race->next = list->next;
107*ff6d591cSmrg   race->next->prev = race;
108*ff6d591cSmrg   list->next = race;
109*ff6d591cSmrg }
110*ff6d591cSmrg 
FindRace(ExpectRace * list,uptr addr,uptr size)111*ff6d591cSmrg static ExpectRace *FindRace(ExpectRace *list, uptr addr, uptr size) {
112*ff6d591cSmrg   for (ExpectRace *race = list->next; race != list; race = race->next) {
113*ff6d591cSmrg     uptr maxbegin = max(race->addr, addr);
114*ff6d591cSmrg     uptr minend = min(race->addr + race->size, addr + size);
115*ff6d591cSmrg     if (maxbegin < minend)
116*ff6d591cSmrg       return race;
117*ff6d591cSmrg   }
118*ff6d591cSmrg   return 0;
119*ff6d591cSmrg }
120*ff6d591cSmrg 
CheckContains(ExpectRace * list,uptr addr,uptr size)121*ff6d591cSmrg static bool CheckContains(ExpectRace *list, uptr addr, uptr size) {
122*ff6d591cSmrg   ExpectRace *race = FindRace(list, addr, size);
123*ff6d591cSmrg   if (race == 0)
124*ff6d591cSmrg     return false;
125*ff6d591cSmrg   DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
126*ff6d591cSmrg       race->desc, race->addr, (int)race->size, race->file, race->line);
127*ff6d591cSmrg   atomic_fetch_add(&race->hitcount, 1, memory_order_relaxed);
128*ff6d591cSmrg   return true;
129*ff6d591cSmrg }
130*ff6d591cSmrg 
InitList(ExpectRace * list)131*ff6d591cSmrg static void InitList(ExpectRace *list) {
132*ff6d591cSmrg   list->next = list;
133*ff6d591cSmrg   list->prev = list;
134*ff6d591cSmrg }
135*ff6d591cSmrg 
InitializeDynamicAnnotations()136*ff6d591cSmrg void InitializeDynamicAnnotations() {
137*ff6d591cSmrg   dyn_ann_ctx = new(dyn_ann_ctx_placeholder) DynamicAnnContext;
138*ff6d591cSmrg   InitList(&dyn_ann_ctx->benign);
139*ff6d591cSmrg }
140*ff6d591cSmrg 
IsExpectedReport(uptr addr,uptr size)141*ff6d591cSmrg bool IsExpectedReport(uptr addr, uptr size) {
142*ff6d591cSmrg   ReadLock lock(&dyn_ann_ctx->mtx);
143*ff6d591cSmrg   return CheckContains(&dyn_ann_ctx->benign, addr, size);
144*ff6d591cSmrg }
145*ff6d591cSmrg }  // namespace __tsan
146*ff6d591cSmrg 
147*ff6d591cSmrg using namespace __tsan;
148*ff6d591cSmrg 
149*ff6d591cSmrg extern "C" {
AnnotateHappensBefore(char * f,int l,uptr addr)150*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
151*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateHappensBefore);
152*ff6d591cSmrg   Release(thr, pc, addr);
153*ff6d591cSmrg }
154*ff6d591cSmrg 
AnnotateHappensAfter(char * f,int l,uptr addr)155*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
156*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateHappensAfter);
157*ff6d591cSmrg   Acquire(thr, pc, addr);
158*ff6d591cSmrg }
159*ff6d591cSmrg 
AnnotateCondVarSignal(char * f,int l,uptr cv)160*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
161*ff6d591cSmrg }
162*ff6d591cSmrg 
AnnotateCondVarSignalAll(char * f,int l,uptr cv)163*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {
164*ff6d591cSmrg }
165*ff6d591cSmrg 
AnnotateMutexIsNotPHB(char * f,int l,uptr mu)166*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {
167*ff6d591cSmrg }
168*ff6d591cSmrg 
AnnotateCondVarWait(char * f,int l,uptr cv,uptr lock)169*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,
170*ff6d591cSmrg                                              uptr lock) {
171*ff6d591cSmrg }
172*ff6d591cSmrg 
AnnotateRWLockCreate(char * f,int l,uptr m)173*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {
174*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateRWLockCreate);
175*ff6d591cSmrg   MutexCreate(thr, pc, m, MutexFlagWriteReentrant);
176*ff6d591cSmrg }
177*ff6d591cSmrg 
AnnotateRWLockCreateStatic(char * f,int l,uptr m)178*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
179*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
180*ff6d591cSmrg   MutexCreate(thr, pc, m, MutexFlagWriteReentrant | MutexFlagLinkerInit);
181*ff6d591cSmrg }
182*ff6d591cSmrg 
AnnotateRWLockDestroy(char * f,int l,uptr m)183*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {
184*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateRWLockDestroy);
185*ff6d591cSmrg   MutexDestroy(thr, pc, m);
186*ff6d591cSmrg }
187*ff6d591cSmrg 
AnnotateRWLockAcquired(char * f,int l,uptr m,uptr is_w)188*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,
189*ff6d591cSmrg                                                 uptr is_w) {
190*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateRWLockAcquired);
191*ff6d591cSmrg   if (is_w)
192*ff6d591cSmrg     MutexPostLock(thr, pc, m, MutexFlagDoPreLockOnPostLock);
193*ff6d591cSmrg   else
194*ff6d591cSmrg     MutexPostReadLock(thr, pc, m, MutexFlagDoPreLockOnPostLock);
195*ff6d591cSmrg }
196*ff6d591cSmrg 
AnnotateRWLockReleased(char * f,int l,uptr m,uptr is_w)197*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,
198*ff6d591cSmrg                                                 uptr is_w) {
199*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateRWLockReleased);
200*ff6d591cSmrg   if (is_w)
201*ff6d591cSmrg     MutexUnlock(thr, pc, m);
202*ff6d591cSmrg   else
203*ff6d591cSmrg     MutexReadUnlock(thr, pc, m);
204*ff6d591cSmrg }
205*ff6d591cSmrg 
AnnotateTraceMemory(char * f,int l,uptr mem)206*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {
207*ff6d591cSmrg }
208*ff6d591cSmrg 
AnnotateFlushState(char * f,int l)209*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {
210*ff6d591cSmrg }
211*ff6d591cSmrg 
AnnotateNewMemory(char * f,int l,uptr mem,uptr size)212*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,
213*ff6d591cSmrg                                            uptr size) {
214*ff6d591cSmrg }
215*ff6d591cSmrg 
AnnotateNoOp(char * f,int l,uptr mem)216*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
217*ff6d591cSmrg }
218*ff6d591cSmrg 
AnnotateFlushExpectedRaces(char * f,int l)219*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {
220*ff6d591cSmrg }
221*ff6d591cSmrg 
AnnotateEnableRaceDetection(char * f,int l,int enable)222*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateEnableRaceDetection(
223*ff6d591cSmrg     char *f, int l, int enable) {
224*ff6d591cSmrg }
225*ff6d591cSmrg 
AnnotateMutexIsUsedAsCondVar(char * f,int l,uptr mu)226*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(
227*ff6d591cSmrg     char *f, int l, uptr mu) {
228*ff6d591cSmrg }
229*ff6d591cSmrg 
AnnotatePCQGet(char * f,int l,uptr pcq)230*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotatePCQGet(
231*ff6d591cSmrg     char *f, int l, uptr pcq) {
232*ff6d591cSmrg }
233*ff6d591cSmrg 
AnnotatePCQPut(char * f,int l,uptr pcq)234*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotatePCQPut(
235*ff6d591cSmrg     char *f, int l, uptr pcq) {
236*ff6d591cSmrg }
237*ff6d591cSmrg 
AnnotatePCQDestroy(char * f,int l,uptr pcq)238*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotatePCQDestroy(
239*ff6d591cSmrg     char *f, int l, uptr pcq) {
240*ff6d591cSmrg }
241*ff6d591cSmrg 
AnnotatePCQCreate(char * f,int l,uptr pcq)242*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotatePCQCreate(
243*ff6d591cSmrg     char *f, int l, uptr pcq) {
244*ff6d591cSmrg }
245*ff6d591cSmrg 
AnnotateExpectRace(char * f,int l,uptr mem,char * desc)246*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateExpectRace(
247*ff6d591cSmrg     char *f, int l, uptr mem, char *desc) {
248*ff6d591cSmrg }
249*ff6d591cSmrg 
BenignRaceImpl(char * f,int l,uptr mem,uptr size,char * desc)250*ff6d591cSmrg static void BenignRaceImpl(char *f, int l, uptr mem, uptr size, char *desc) {
251*ff6d591cSmrg   Lock lock(&dyn_ann_ctx->mtx);
252*ff6d591cSmrg   AddExpectRace(&dyn_ann_ctx->benign,
253*ff6d591cSmrg                 f, l, mem, size, desc);
254*ff6d591cSmrg   DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc, mem, f, l);
255*ff6d591cSmrg }
256*ff6d591cSmrg 
AnnotateBenignRaceSized(char * f,int l,uptr mem,uptr size,char * desc)257*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateBenignRaceSized(
258*ff6d591cSmrg     char *f, int l, uptr mem, uptr size, char *desc) {
259*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateBenignRaceSized);
260*ff6d591cSmrg   BenignRaceImpl(f, l, mem, size, desc);
261*ff6d591cSmrg }
262*ff6d591cSmrg 
AnnotateBenignRace(char * f,int l,uptr mem,char * desc)263*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateBenignRace(
264*ff6d591cSmrg     char *f, int l, uptr mem, char *desc) {
265*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateBenignRace);
266*ff6d591cSmrg   BenignRaceImpl(f, l, mem, 1, desc);
267*ff6d591cSmrg }
268*ff6d591cSmrg 
AnnotateIgnoreReadsBegin(char * f,int l)269*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {
270*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);
271*ff6d591cSmrg   ThreadIgnoreBegin(thr, pc);
272*ff6d591cSmrg }
273*ff6d591cSmrg 
AnnotateIgnoreReadsEnd(char * f,int l)274*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {
275*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);
276*ff6d591cSmrg   ThreadIgnoreEnd(thr);
277*ff6d591cSmrg }
278*ff6d591cSmrg 
AnnotateIgnoreWritesBegin(char * f,int l)279*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
280*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);
281*ff6d591cSmrg   ThreadIgnoreBegin(thr, pc);
282*ff6d591cSmrg }
283*ff6d591cSmrg 
AnnotateIgnoreWritesEnd(char * f,int l)284*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
285*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
286*ff6d591cSmrg   ThreadIgnoreEnd(thr);
287*ff6d591cSmrg }
288*ff6d591cSmrg 
AnnotateIgnoreSyncBegin(char * f,int l)289*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncBegin(char *f, int l) {
290*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin);
291*ff6d591cSmrg   ThreadIgnoreSyncBegin(thr, pc);
292*ff6d591cSmrg }
293*ff6d591cSmrg 
AnnotateIgnoreSyncEnd(char * f,int l)294*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncEnd(char *f, int l) {
295*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd);
296*ff6d591cSmrg   ThreadIgnoreSyncEnd(thr);
297*ff6d591cSmrg }
298*ff6d591cSmrg 
AnnotatePublishMemoryRange(char * f,int l,uptr addr,uptr size)299*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
300*ff6d591cSmrg     char *f, int l, uptr addr, uptr size) {
301*ff6d591cSmrg }
302*ff6d591cSmrg 
AnnotateUnpublishMemoryRange(char * f,int l,uptr addr,uptr size)303*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
304*ff6d591cSmrg     char *f, int l, uptr addr, uptr size) {
305*ff6d591cSmrg }
306*ff6d591cSmrg 
AnnotateThreadName(char * f,int l,char * name)307*ff6d591cSmrg void INTERFACE_ATTRIBUTE AnnotateThreadName(
308*ff6d591cSmrg     char *f, int l, char *name) {
309*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateThreadName);
310*ff6d591cSmrg   ThreadSetName(thr, name);
311*ff6d591cSmrg }
312*ff6d591cSmrg 
313*ff6d591cSmrg // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
314*ff6d591cSmrg // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
315*ff6d591cSmrg // atomic operations, which should be handled by ThreadSanitizer correctly.
WTFAnnotateHappensBefore(char * f,int l,uptr addr)316*ff6d591cSmrg void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
317*ff6d591cSmrg }
318*ff6d591cSmrg 
WTFAnnotateHappensAfter(char * f,int l,uptr addr)319*ff6d591cSmrg void INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {
320*ff6d591cSmrg }
321*ff6d591cSmrg 
WTFAnnotateBenignRaceSized(char * f,int l,uptr mem,uptr sz,char * desc)322*ff6d591cSmrg void INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(
323*ff6d591cSmrg     char *f, int l, uptr mem, uptr sz, char *desc) {
324*ff6d591cSmrg   SCOPED_ANNOTATION(AnnotateBenignRaceSized);
325*ff6d591cSmrg   BenignRaceImpl(f, l, mem, sz, desc);
326*ff6d591cSmrg }
327*ff6d591cSmrg 
RunningOnValgrind()328*ff6d591cSmrg int INTERFACE_ATTRIBUTE RunningOnValgrind() {
329*ff6d591cSmrg   return flags()->running_on_valgrind;
330*ff6d591cSmrg }
331*ff6d591cSmrg 
ValgrindSlowdown(void)332*ff6d591cSmrg double __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {
333*ff6d591cSmrg   return 10.0;
334*ff6d591cSmrg }
335*ff6d591cSmrg 
ThreadSanitizerQuery(const char * query)336*ff6d591cSmrg const char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {
337*ff6d591cSmrg   if (internal_strcmp(query, "pure_happens_before") == 0)
338*ff6d591cSmrg     return "1";
339*ff6d591cSmrg   else
340*ff6d591cSmrg     return "0";
341*ff6d591cSmrg }
342*ff6d591cSmrg 
343*ff6d591cSmrg void INTERFACE_ATTRIBUTE
AnnotateMemoryIsInitialized(char * f,int l,uptr mem,uptr sz)344*ff6d591cSmrg AnnotateMemoryIsInitialized(char *f, int l, uptr mem, uptr sz) {}
345*ff6d591cSmrg void INTERFACE_ATTRIBUTE
AnnotateMemoryIsUninitialized(char * f,int l,uptr mem,uptr sz)346*ff6d591cSmrg AnnotateMemoryIsUninitialized(char *f, int l, uptr mem, uptr sz) {}
347*ff6d591cSmrg 
348*ff6d591cSmrg // Note: the parameter is called flagz, because flags is already taken
349*ff6d591cSmrg // by the global function that returns flags.
350*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_create(void * m,unsigned flagz)351*ff6d591cSmrg void __tsan_mutex_create(void *m, unsigned flagz) {
352*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_create);
353*ff6d591cSmrg   MutexCreate(thr, pc, (uptr)m, flagz & MutexCreationFlagMask);
354*ff6d591cSmrg }
355*ff6d591cSmrg 
356*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_destroy(void * m,unsigned flagz)357*ff6d591cSmrg void __tsan_mutex_destroy(void *m, unsigned flagz) {
358*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_destroy);
359*ff6d591cSmrg   MutexDestroy(thr, pc, (uptr)m, flagz);
360*ff6d591cSmrg }
361*ff6d591cSmrg 
362*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_pre_lock(void * m,unsigned flagz)363*ff6d591cSmrg void __tsan_mutex_pre_lock(void *m, unsigned flagz) {
364*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_pre_lock);
365*ff6d591cSmrg   if (!(flagz & MutexFlagTryLock)) {
366*ff6d591cSmrg     if (flagz & MutexFlagReadLock)
367*ff6d591cSmrg       MutexPreReadLock(thr, pc, (uptr)m);
368*ff6d591cSmrg     else
369*ff6d591cSmrg       MutexPreLock(thr, pc, (uptr)m);
370*ff6d591cSmrg   }
371*ff6d591cSmrg   ThreadIgnoreBegin(thr, 0);
372*ff6d591cSmrg   ThreadIgnoreSyncBegin(thr, 0);
373*ff6d591cSmrg }
374*ff6d591cSmrg 
375*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_post_lock(void * m,unsigned flagz,int rec)376*ff6d591cSmrg void __tsan_mutex_post_lock(void *m, unsigned flagz, int rec) {
377*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_post_lock);
378*ff6d591cSmrg   ThreadIgnoreSyncEnd(thr);
379*ff6d591cSmrg   ThreadIgnoreEnd(thr);
380*ff6d591cSmrg   if (!(flagz & MutexFlagTryLockFailed)) {
381*ff6d591cSmrg     if (flagz & MutexFlagReadLock)
382*ff6d591cSmrg       MutexPostReadLock(thr, pc, (uptr)m, flagz);
383*ff6d591cSmrg     else
384*ff6d591cSmrg       MutexPostLock(thr, pc, (uptr)m, flagz, rec);
385*ff6d591cSmrg   }
386*ff6d591cSmrg }
387*ff6d591cSmrg 
388*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_pre_unlock(void * m,unsigned flagz)389*ff6d591cSmrg int __tsan_mutex_pre_unlock(void *m, unsigned flagz) {
390*ff6d591cSmrg   SCOPED_ANNOTATION_RET(__tsan_mutex_pre_unlock, 0);
391*ff6d591cSmrg   int ret = 0;
392*ff6d591cSmrg   if (flagz & MutexFlagReadLock) {
393*ff6d591cSmrg     CHECK(!(flagz & MutexFlagRecursiveUnlock));
394*ff6d591cSmrg     MutexReadUnlock(thr, pc, (uptr)m);
395*ff6d591cSmrg   } else {
396*ff6d591cSmrg     ret = MutexUnlock(thr, pc, (uptr)m, flagz);
397*ff6d591cSmrg   }
398*ff6d591cSmrg   ThreadIgnoreBegin(thr, 0);
399*ff6d591cSmrg   ThreadIgnoreSyncBegin(thr, 0);
400*ff6d591cSmrg   return ret;
401*ff6d591cSmrg }
402*ff6d591cSmrg 
403*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_post_unlock(void * m,unsigned flagz)404*ff6d591cSmrg void __tsan_mutex_post_unlock(void *m, unsigned flagz) {
405*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_post_unlock);
406*ff6d591cSmrg   ThreadIgnoreSyncEnd(thr);
407*ff6d591cSmrg   ThreadIgnoreEnd(thr);
408*ff6d591cSmrg }
409*ff6d591cSmrg 
410*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_pre_signal(void * addr,unsigned flagz)411*ff6d591cSmrg void __tsan_mutex_pre_signal(void *addr, unsigned flagz) {
412*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_pre_signal);
413*ff6d591cSmrg   ThreadIgnoreBegin(thr, 0);
414*ff6d591cSmrg   ThreadIgnoreSyncBegin(thr, 0);
415*ff6d591cSmrg }
416*ff6d591cSmrg 
417*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_post_signal(void * addr,unsigned flagz)418*ff6d591cSmrg void __tsan_mutex_post_signal(void *addr, unsigned flagz) {
419*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_post_signal);
420*ff6d591cSmrg   ThreadIgnoreSyncEnd(thr);
421*ff6d591cSmrg   ThreadIgnoreEnd(thr);
422*ff6d591cSmrg }
423*ff6d591cSmrg 
424*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_pre_divert(void * addr,unsigned flagz)425*ff6d591cSmrg void __tsan_mutex_pre_divert(void *addr, unsigned flagz) {
426*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_pre_divert);
427*ff6d591cSmrg   // Exit from ignore region started in __tsan_mutex_pre_lock/unlock/signal.
428*ff6d591cSmrg   ThreadIgnoreSyncEnd(thr);
429*ff6d591cSmrg   ThreadIgnoreEnd(thr);
430*ff6d591cSmrg }
431*ff6d591cSmrg 
432*ff6d591cSmrg INTERFACE_ATTRIBUTE
__tsan_mutex_post_divert(void * addr,unsigned flagz)433*ff6d591cSmrg void __tsan_mutex_post_divert(void *addr, unsigned flagz) {
434*ff6d591cSmrg   SCOPED_ANNOTATION(__tsan_mutex_post_divert);
435*ff6d591cSmrg   ThreadIgnoreBegin(thr, 0);
436*ff6d591cSmrg   ThreadIgnoreSyncBegin(thr, 0);
437*ff6d591cSmrg }
438*ff6d591cSmrg }  // extern "C"
439