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