1 //===-- tsan_update_shadow_word_inl.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 // Body of the hottest inner loop.
11 // If we wrap this body into a function, compilers (both gcc and clang)
12 // produce sligtly less efficient code.
13 //===----------------------------------------------------------------------===//
15 StatInc(thr
, StatShadowProcessed
);
16 const unsigned kAccessSize
= 1 << kAccessSizeLog
;
17 u64
*sp
= &shadow_mem
[idx
];
20 StatInc(thr
, StatShadowZero
);
22 StoreIfNotYetStored(sp
, &store_word
);
23 // The above StoreIfNotYetStored could be done unconditionally
24 // and it even shows 4% gain on synthetic benchmarks (r4307).
27 // is the memory access equal to the previous?
28 if (Shadow::Addr0AndSizeAreEqual(cur
, old
)) {
29 StatInc(thr
, StatShadowSameSize
);
31 if (Shadow::TidsAreEqual(old
, cur
)) {
32 StatInc(thr
, StatShadowSameThread
);
33 if (old
.IsRWWeakerOrEqual(kAccessIsWrite
, kIsAtomic
))
34 StoreIfNotYetStored(sp
, &store_word
);
37 StatInc(thr
, StatShadowAnotherThread
);
38 if (HappensBefore(old
, thr
)) {
39 if (old
.IsRWWeakerOrEqual(kAccessIsWrite
, kIsAtomic
))
40 StoreIfNotYetStored(sp
, &store_word
);
43 if (old
.IsBothReadsOrAtomic(kAccessIsWrite
, kIsAtomic
))
47 // Do the memory access intersect?
48 if (Shadow::TwoRangesIntersect(old
, cur
, kAccessSize
)) {
49 StatInc(thr
, StatShadowIntersect
);
50 if (Shadow::TidsAreEqual(old
, cur
)) {
51 StatInc(thr
, StatShadowSameThread
);
54 StatInc(thr
, StatShadowAnotherThread
);
55 if (old
.IsBothReadsOrAtomic(kAccessIsWrite
, kIsAtomic
))
57 if (HappensBefore(old
, thr
))
61 // The accesses do not intersect.
62 StatInc(thr
, StatShadowNotIntersect
);