Changeset View
Changeset View
Standalone View
Standalone View
lib/scudo/scudo_tsd_shared.cpp
Show All 11 Lines | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "scudo_tsd.h" | #include "scudo_tsd.h" | ||||
#if !SCUDO_TSD_EXCLUSIVE | #if !SCUDO_TSD_EXCLUSIVE | ||||
namespace __scudo { | namespace __scudo { | ||||
#if !SANITIZER_WINDOWS | |||||
static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT; | static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT; | ||||
pthread_key_t PThreadKey; | pthread_key_t PThreadKey; | ||||
#else | |||||
DWORD TlsIndex = TLS_OUT_OF_INDEXES; | |||||
static INIT_ONCE InitOnce = INIT_ONCE_STATIC_INIT; | |||||
#endif | |||||
static atomic_uint32_t CurrentIndex; | static atomic_uint32_t CurrentIndex; | ||||
static ScudoTSD *TSDs; | static ScudoTSD *TSDs; | ||||
static u32 NumberOfTSDs; | static u32 NumberOfTSDs; | ||||
static void initOnce() { | static void initOnce() { | ||||
#if SANITIZER_WINDOWS | |||||
TlsIndex = TlsAlloc(); | |||||
CHECK_NE(TlsIndex, TLS_OUT_OF_INDEXES); | |||||
#elif !SANITIZER_ANDROID | |||||
CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0); | CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0); | ||||
#endif | |||||
initScudo(); | initScudo(); | ||||
NumberOfTSDs = Min(Max(1U, GetNumberOfCPUsCached()), | NumberOfTSDs = Min(Max(1U, GetNumberOfCPUsCached()), | ||||
static_cast<u32>(SCUDO_SHARED_TSD_POOL_SIZE)); | static_cast<u32>(SCUDO_SHARED_TSD_POOL_SIZE)); | ||||
TSDs = reinterpret_cast<ScudoTSD *>( | TSDs = reinterpret_cast<ScudoTSD *>( | ||||
MmapOrDie(sizeof(ScudoTSD) * NumberOfTSDs, "ScudoTSDs")); | MmapOrDie(sizeof(ScudoTSD) * NumberOfTSDs, "ScudoTSDs")); | ||||
for (u32 i = 0; i < NumberOfTSDs; i++) | for (u32 i = 0; i < NumberOfTSDs; i++) | ||||
TSDs[i].init(/*Shared=*/true); | TSDs[i].init(/*Shared=*/true); | ||||
} | } | ||||
ALWAYS_INLINE void setCurrentTSD(ScudoTSD *TSD) { | ALWAYS_INLINE void setCurrentTSD(ScudoTSD *TSD) { | ||||
#if SANITIZER_ANDROID | #if SANITIZER_WINDOWS | ||||
CHECK(TlsSetValue(TlsIndex, reinterpret_cast<LPVOID>(TSD))); | |||||
#elif SANITIZER_ANDROID | |||||
*get_android_tls_ptr() = reinterpret_cast<uptr>(TSD); | *get_android_tls_ptr() = reinterpret_cast<uptr>(TSD); | ||||
#else | #else | ||||
CHECK_EQ(pthread_setspecific(PThreadKey, reinterpret_cast<void *>(TSD)), 0); | CHECK_EQ(pthread_setspecific(PThreadKey, reinterpret_cast<void *>(TSD)), 0); | ||||
#endif // SANITIZER_ANDROID | #endif // SANITIZER_ANDROID | ||||
} | } | ||||
#if SANITIZER_WINDOWS | |||||
static BOOL CALLBACK handleInit(PINIT_ONCE InitOnce, PVOID Parameter, | |||||
PVOID *Context) { | |||||
initOnce(); | |||||
return TRUE; | |||||
} | |||||
#endif | |||||
void initThread(bool MinimalInit) { | void initThread(bool MinimalInit) { | ||||
#if SANITIZER_WINDOWS | |||||
CHECK(InitOnceExecuteOnce(&InitOnce, handleInit, nullptr, nullptr)); | |||||
#else | |||||
pthread_once(&GlobalInitialized, initOnce); | pthread_once(&GlobalInitialized, initOnce); | ||||
#endif | |||||
// Initial context assignment is done in a plain round-robin fashion. | // Initial context assignment is done in a plain round-robin fashion. | ||||
u32 Index = atomic_fetch_add(&CurrentIndex, 1, memory_order_relaxed); | u32 Index = atomic_fetch_add(&CurrentIndex, 1, memory_order_relaxed); | ||||
setCurrentTSD(&TSDs[Index % NumberOfTSDs]); | setCurrentTSD(&TSDs[Index % NumberOfTSDs]); | ||||
} | } | ||||
ScudoTSD *getTSDAndLockSlow() { | ScudoTSD *getTSDAndLockSlow() { | ||||
ScudoTSD *TSD; | ScudoTSD *TSD; | ||||
if (NumberOfTSDs > 1) { | if (NumberOfTSDs > 1) { | ||||
Show All 32 Lines |