Add a flag to force tsan's background thread

Reviewed By: dvyukov, vitalybuka

Differential Revision: https://reviews.llvm.org/D115759
This commit is contained in:
Matt Kulukundis 2021-12-16 11:45:49 -08:00 committed by Vitaly Buka
parent 9043c3d65b
commit 406b538dea
3 changed files with 36 additions and 0 deletions

View File

@ -43,6 +43,9 @@ TSAN_FLAG(
bool, force_seq_cst_atomics, false,
"If set, all atomics are effectively sequentially consistent (seq_cst), "
"regardless of what user actually specified.")
TSAN_FLAG(bool, force_background_thread, false,
"If set, eagerly launch a background thread for memory reclamation "
"instead of waiting for a user call to pthread_create.")
TSAN_FLAG(bool, halt_on_error, false, "Exit after first reported error.")
TSAN_FLAG(int, atexit_sleep_ms, 1000,
"Sleep in main thread before exiting for that many ms "

View File

@ -698,6 +698,18 @@ void Initialize(ThreadState *thr) {
OnInitialize();
}
#if !SANITIZER_GO
# pragma clang diagnostic push
// We intentionally use a global constructor to delay the pthread call.
# pragma clang diagnostic ignored "-Wglobal-constructors"
static bool UNUSED __local_tsan_dyninit = [] {
if (flags()->force_background_thread)
MaybeSpawnBackgroundThread();
return false;
}();
# pragma clang diagnostic pop
#endif
void MaybeSpawnBackgroundThread() {
// On MIPS, TSan initialization is run before
// __pthread_initialize_minimal_internal() is finished, so we can not spawn

View File

@ -0,0 +1,21 @@
// RUN: %clangxx_tsan -O1 %s -o %t
// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000 %run %t 2>&1 | FileCheck %s --implicit-check-not "memory flush check"
// RUN: %deflake %env_tsan_opts=force_background_thread=1:verbosity=1:memory_limit_mb=1000 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD
// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000 %run %t 1 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD
#include "test.h"
void *Thread(void *a) { return nullptr; }
int main(int argc, char *argv[]) {
if (argc > 1) {
pthread_t t;
pthread_create(&t, nullptr, Thread, nullptr);
void *p;
pthread_join(t, &p);
}
sleep(3);
return 1;
}
// CHECK: Running under ThreadSanitizer
// THREAD: ThreadSanitizer: memory flush check