]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/scudo/scudo_tls_linux.cpp
MFV r316861: 6866 zdb -l should return non-zero if it fails to find any label
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / scudo / scudo_tls_linux.cpp
1 //===-- scudo_tls_linux.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// Scudo thread local structure implementation for platforms supporting
11 /// thread_local.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "sanitizer_common/sanitizer_platform.h"
16
17 #if SANITIZER_LINUX && !SANITIZER_ANDROID
18
19 #include "scudo_tls.h"
20
21 #include <pthread.h>
22
23 namespace __scudo {
24
25 static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
26 static pthread_key_t PThreadKey;
27
28 __attribute__((tls_model("initial-exec")))
29 THREADLOCAL ThreadState ScudoThreadState = ThreadNotInitialized;
30 __attribute__((tls_model("initial-exec")))
31 THREADLOCAL ScudoThreadContext ThreadLocalContext;
32
33 static void teardownThread(void *Ptr) {
34   uptr I = reinterpret_cast<uptr>(Ptr);
35   // The glibc POSIX thread-local-storage deallocation routine calls user
36   // provided destructors in a loop of PTHREAD_DESTRUCTOR_ITERATIONS.
37   // We want to be called last since other destructors might call free and the
38   // like, so we wait until PTHREAD_DESTRUCTOR_ITERATIONS before draining the
39   // quarantine and swallowing the cache.
40   if (I > 1) {
41     // If pthread_setspecific fails, we will go ahead with the teardown.
42     if (LIKELY(pthread_setspecific(PThreadKey,
43                                    reinterpret_cast<void *>(I - 1)) == 0))
44       return;
45   }
46   ThreadLocalContext.commitBack();
47   ScudoThreadState = ThreadTornDown;
48 }
49
50
51 static void initOnce() {
52   CHECK_EQ(pthread_key_create(&PThreadKey, teardownThread), 0);
53   initScudo();
54 }
55
56 void initThread() {
57   CHECK_EQ(pthread_once(&GlobalInitialized, initOnce), 0);
58   CHECK_EQ(pthread_setspecific(PThreadKey, reinterpret_cast<void *>(
59       GetPthreadDestructorIterations())), 0);
60   ThreadLocalContext.init();
61   ScudoThreadState = ThreadInitialized;
62 }
63
64 }  // namespace __scudo
65
66 #endif  // SANITIZER_LINUX && !SANITIZER_ANDROID