buildtools/gcc/libsanitizer/tsan/tsan_update_shadow_word_inl.h

70 lines
2.2 KiB
C
Raw Normal View History

2013-06-05 18:35:38 +02:00
//===-- tsan_update_shadow_word_inl.h ---------------------------*- C++ -*-===//
//
2021-12-06 21:18:24 +00:00
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2013-06-05 18:35:38 +02:00
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
// Body of the hottest inner loop.
// If we wrap this body into a function, compilers (both gcc and clang)
// produce sligtly less efficient code.
//===----------------------------------------------------------------------===//
do {
StatInc(thr, StatShadowProcessed);
const unsigned kAccessSize = 1 << kAccessSizeLog;
2016-02-29 10:41:25 +01:00
u64 *sp = &shadow_mem[idx];
2013-06-05 18:35:38 +02:00
old = LoadShadow(sp);
2021-12-06 21:18:24 +00:00
if (LIKELY(old.IsZero())) {
2013-06-05 18:35:38 +02:00
StatInc(thr, StatShadowZero);
2021-12-06 21:18:24 +00:00
if (!stored) {
2013-06-05 18:35:38 +02:00
StoreIfNotYetStored(sp, &store_word);
2021-12-06 21:18:24 +00:00
stored = true;
}
2013-06-05 18:35:38 +02:00
break;
}
// is the memory access equal to the previous?
2021-12-06 21:18:24 +00:00
if (LIKELY(Shadow::Addr0AndSizeAreEqual(cur, old))) {
2013-06-05 18:35:38 +02:00
StatInc(thr, StatShadowSameSize);
// same thread?
2021-12-06 21:18:24 +00:00
if (LIKELY(Shadow::TidsAreEqual(old, cur))) {
2013-06-05 18:35:38 +02:00
StatInc(thr, StatShadowSameThread);
2021-12-06 21:18:24 +00:00
if (LIKELY(old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))) {
2013-06-05 18:35:38 +02:00
StoreIfNotYetStored(sp, &store_word);
2021-12-06 21:18:24 +00:00
stored = true;
}
2013-06-05 18:35:38 +02:00
break;
}
StatInc(thr, StatShadowAnotherThread);
if (HappensBefore(old, thr)) {
2021-12-06 21:18:24 +00:00
if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) {
2018-03-19 15:31:14 -05:00
StoreIfNotYetStored(sp, &store_word);
2021-12-06 21:18:24 +00:00
stored = true;
}
2013-06-05 18:35:38 +02:00
break;
}
2021-12-06 21:18:24 +00:00
if (LIKELY(old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic)))
2013-06-05 18:35:38 +02:00
break;
goto RACE;
}
// Do the memory access intersect?
2016-02-29 10:41:25 +01:00
if (Shadow::TwoRangesIntersect(old, cur, kAccessSize)) {
2013-06-05 18:35:38 +02:00
StatInc(thr, StatShadowIntersect);
if (Shadow::TidsAreEqual(old, cur)) {
StatInc(thr, StatShadowSameThread);
break;
}
StatInc(thr, StatShadowAnotherThread);
if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
break;
2021-12-06 21:18:24 +00:00
if (LIKELY(HappensBefore(old, thr)))
2013-06-05 18:35:38 +02:00
break;
goto RACE;
}
// The accesses do not intersect.
StatInc(thr, StatShadowNotIntersect);
break;
} while (0);