diff --git a/compiler-rt/lib/scudo/scudo_tsd_shared.cpp b/compiler-rt/lib/scudo/scudo_tsd_shared.cpp --- a/compiler-rt/lib/scudo/scudo_tsd_shared.cpp +++ b/compiler-rt/lib/scudo/scudo_tsd_shared.cpp @@ -17,6 +17,7 @@ namespace __scudo { static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT; +atomic_uint32_t ScudoInitted; pthread_key_t PThreadKey; static atomic_uint32_t CurrentIndex; @@ -32,7 +33,6 @@ static void initOnce() { CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0); - initScudo(); NumberOfTSDs = Min(Max(1U, GetNumberOfCPUsCached()), static_cast(SCUDO_SHARED_TSD_POOL_SIZE)); TSDs = reinterpret_cast( @@ -57,6 +57,11 @@ #endif // SANITIZER_ANDROID } +void InitScudoOnce() { + u32 Initted = atomic_fetch_add(&ScudoInitted, 1, memory_order_relaxed); + if (UNLIKELY(!Initted)) + initScudo(); +} void initThread(bool MinimalInit) { pthread_once(&GlobalInitialized, initOnce); // Initial context assignment is done in a plain round-robin fashion. diff --git a/compiler-rt/lib/scudo/scudo_tsd_shared.inc b/compiler-rt/lib/scudo/scudo_tsd_shared.inc --- a/compiler-rt/lib/scudo/scudo_tsd_shared.inc +++ b/compiler-rt/lib/scudo/scudo_tsd_shared.inc @@ -17,6 +17,7 @@ #if !SCUDO_TSD_EXCLUSIVE extern pthread_key_t PThreadKey; +extern void InitScudoOnce(); #if SANITIZER_LINUX && !SANITIZER_ANDROID __attribute__((tls_model("initial-exec"))) @@ -34,8 +35,9 @@ } ALWAYS_INLINE void initThreadMaybe(bool MinimalInit = false) { + InitScudoOnce(); if (LIKELY(getCurrentTSD())) - return; + return; initThread(MinimalInit); }