1 //===-- memprof_posix.cpp ------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of MemProfiler, a memory profiler.
10 //
11 // Posix-specific details.
12 //===----------------------------------------------------------------------===//
13 
14 #include "sanitizer_common/sanitizer_platform.h"
15 #if !SANITIZER_POSIX
16 #error Only Posix supported
17 #endif
18 
19 #include "memprof_thread.h"
20 #include "sanitizer_common/sanitizer_internal_defs.h"
21 
22 #include <pthread.h>
23 
24 namespace __memprof {
25 
26 // ---------------------- TSD ---------------- {{{1
27 
28 static pthread_key_t tsd_key;
29 static bool tsd_key_inited = false;
TSDInit(void (* destructor)(void * tsd))30 void TSDInit(void (*destructor)(void *tsd)) {
31   CHECK(!tsd_key_inited);
32   tsd_key_inited = true;
33   CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
34 }
35 
TSDGet()36 void *TSDGet() {
37   CHECK(tsd_key_inited);
38   return pthread_getspecific(tsd_key);
39 }
40 
TSDSet(void * tsd)41 void TSDSet(void *tsd) {
42   CHECK(tsd_key_inited);
43   pthread_setspecific(tsd_key, tsd);
44 }
45 
PlatformTSDDtor(void * tsd)46 void PlatformTSDDtor(void *tsd) {
47   MemprofThreadContext *context = (MemprofThreadContext *)tsd;
48   if (context->destructor_iterations > 1) {
49     context->destructor_iterations--;
50     CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
51     return;
52   }
53   MemprofThread::TSDDtor(tsd);
54 }
55 } // namespace __memprof
56