Index: lib/asan/asan_posix.cc =================================================================== --- lib/asan/asan_posix.cc +++ lib/asan/asan_posix.cc @@ -40,31 +40,44 @@ // ---------------------- TSD ---------------- {{{1 -static pthread_key_t tsd_key; +struct TsdKey { + void *data; + void (*dst)(void *value); + TsdKey() : data(nullptr), dst(nullptr) {} + ~TsdKey() { + AsanThreadContext *context = (AsanThreadContext*)data; + if (context->destructor_iterations > 1) { + context->destructor_iterations--; + return; + } + + if (dst) + dst(data); + } +}; + +static const size_t dit = GetPthreadDestructorIterations(); +static thread_local TsdKey Tsd[4]; static bool tsd_key_inited = false; void AsanTSDInit(void (*destructor)(void *tsd)) { CHECK(!tsd_key_inited); tsd_key_inited = true; - CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); + for (size_t i = 0; i < dit; i ++) + Tsd[i].dst = destructor; } void *AsanTSDGet() { CHECK(tsd_key_inited); - return pthread_getspecific(tsd_key); + return Tsd[0].data; } void AsanTSDSet(void *tsd) { CHECK(tsd_key_inited); - pthread_setspecific(tsd_key, tsd); + for (size_t i = 0; i < dit; i ++) + Tsd[i].data = tsd; } void PlatformTSDDtor(void *tsd) { - AsanThreadContext *context = (AsanThreadContext*)tsd; - if (context->destructor_iterations > 1) { - context->destructor_iterations--; - CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); - return; - } AsanThread::TSDDtor(tsd); } } // namespace __asan