tsan: introduce LazyInitialize

We call non-inlinable Initialize from all interceptors/syscalls,
but most of the time runtime is already initialized and this just
introduces unnecessary overhead.
Add LazyInitialize that (1) inlinable, (2) does nothing if
.preinit_array is enabled (expected case on Linux).

Depends on D107071.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D107072
This commit is contained in:
Dmitry Vyukov 2021-07-29 13:50:29 +02:00
parent 17f650cb00
commit 9e9599ef78
3 changed files with 17 additions and 6 deletions

View File

@ -249,7 +249,7 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) {
ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
uptr pc)
: thr_(thr), in_ignored_lib_(false), ignoring_(false) {
Initialize(thr);
LazyInitialize(thr);
if (!thr_->is_inited) return;
if (!thr_->ignore_interceptors) FuncEntry(thr, pc);
DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
@ -2488,10 +2488,7 @@ static __sanitizer_sighandler_ptr signal_impl(int sig,
struct ScopedSyscall {
ThreadState *thr;
explicit ScopedSyscall(ThreadState *thr)
: thr(thr) {
Initialize(thr);
}
explicit ScopedSyscall(ThreadState *thr) : thr(thr) { LazyInitialize(thr); }
~ScopedSyscall() {
ProcessPendingSignals(thr);

View File

@ -384,9 +384,10 @@ void CheckUnwind() {
PrintCurrentStackSlow(StackTrace::GetCurrentPc());
}
bool is_initialized;
void Initialize(ThreadState *thr) {
// Thread safe because done before all threads exist.
static bool is_initialized = false;
if (is_initialized)
return;
is_initialized = true;

View File

@ -859,6 +859,19 @@ enum FiberSwitchFlags {
FiberSwitchFlagNoSync = 1 << 0, // __tsan_switch_to_fiber_no_sync
};
extern bool is_initialized;
ALWAYS_INLINE
void LazyInitialize(ThreadState *thr) {
// If we can use .preinit_array, assume that __tsan_init
// called from .preinit_array initializes runtime before
// any instrumented code.
#if !SANITIZER_CAN_USE_PREINIT_ARRAY
if (UNLIKELY(!is_initialized))
Initialize(thr);
#endif
}
} // namespace __tsan
#endif // TSAN_RTL_H