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