diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:55 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:55 +0000 |
commit | 8d8e909cdc9f4e78e1e1600497d827e1acde6cea (patch) | |
tree | c8c6047827589e56f2ed1f77f23b1f7d1a10e793 /lib/scudo/scudo_tls_linux.cpp | |
parent | 2953104c9a262728031dc518429d15b969dd6028 (diff) |
Diffstat (limited to 'lib/scudo/scudo_tls_linux.cpp')
-rw-r--r-- | lib/scudo/scudo_tls_linux.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/scudo/scudo_tls_linux.cpp b/lib/scudo/scudo_tls_linux.cpp new file mode 100644 index 000000000000..3453367f8a53 --- /dev/null +++ b/lib/scudo/scudo_tls_linux.cpp @@ -0,0 +1,62 @@ +//===-- scudo_tls_linux.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// Scudo thread local structure implementation for platforms supporting +/// thread_local. +/// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" + +#if SANITIZER_LINUX + +#include "scudo_tls.h" + +#include <limits.h> +#include <pthread.h> + +namespace __scudo { + +static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT; +static pthread_key_t PThreadKey; + +thread_local ThreadState ScudoThreadState = ThreadNotInitialized; +thread_local ScudoThreadContext ThreadLocalContext; + +static void teardownThread(void *Ptr) { + uptr Iteration = reinterpret_cast<uptr>(Ptr); + // The glibc POSIX thread-local-storage deallocation routine calls user + // provided destructors in a loop of PTHREAD_DESTRUCTOR_ITERATIONS. + // We want to be called last since other destructors might call free and the + // like, so we wait until PTHREAD_DESTRUCTOR_ITERATIONS before draining the + // quarantine and swallowing the cache. + if (Iteration < PTHREAD_DESTRUCTOR_ITERATIONS) { + pthread_setspecific(PThreadKey, reinterpret_cast<void *>(Iteration + 1)); + return; + } + ThreadLocalContext.commitBack(); + ScudoThreadState = ThreadTornDown; +} + + +static void initOnce() { + CHECK_EQ(pthread_key_create(&PThreadKey, teardownThread), 0); + initScudo(); +} + +void initThread() { + pthread_once(&GlobalInitialized, initOnce); + pthread_setspecific(PThreadKey, reinterpret_cast<void *>(1)); + ThreadLocalContext.init(); + ScudoThreadState = ThreadInitialized; +} + +} // namespace __scudo + +#endif // SANITIZER_LINUX |