Skip to content

Commit 2c37645

Browse files
committed
Remove pthread_key and use initial-exec TLS instead
1 parent dee61e6 commit 2c37645

5 files changed

Lines changed: 17 additions & 22 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ if(BUILD_UNIVERSAL_DDPROF)
267267
endif()
268268
endif()
269269

270+
if(USE_LOADER)
271+
target_compile_definitions(dd_profiling-embedded PRIVATE "DDPROF_USE_LOADER")
272+
endif()
273+
270274
# Fix for link error in sanitizeddebug build mode with gcc:
271275
# ~~~
272276
# /usr/bin/ld: ./libdd_profiling.so: undefined reference to `__dynamic_cast'

cmake/dd_profiling.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
global: ddprof_start_profiling; ddprof_stop_profiling;
2+
global: ddprof_start_profiling; ddprof_stop_profiling; ddprof_lib_state;
33
local: *;
44
};

include/lib/allocation_tracker.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ class AllocationTracker {
120120

121121
static void delete_tl_state(void *tl_state);
122122

123-
static void make_key();
124-
125123
void track_allocation(uintptr_t addr, size_t size,
126124
TrackerThreadLocalState &tl_state, bool is_large_alloc);
127125
void track_deallocation(uintptr_t addr, TrackerThreadLocalState &tl_state,

src/lib/allocation_tracker.cc

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
#include <cstdlib>
2626
#include <unistd.h>
2727

28+
#ifdef DDPROF_USE_LOADER
29+
extern "C"
30+
__attribute((tls_model("initial-exec"))) __thread void *ddprof_lib_state;
31+
#else
32+
__attribute((tls_model("initial-exec"))) __thread void *ddprof_lib_state;
33+
#endif
34+
2835
namespace ddprof {
2936

3037
// Static declarations
@@ -53,13 +60,7 @@ DDPROF_NOINLINE auto sleep_and_retry_reserve(MPSCRingBufferWriter &writer,
5360
} // namespace
5461

5562
TrackerThreadLocalState *AllocationTracker::get_tl_state() {
56-
// In shared libraries, TLS access requires a call to tls_get_addr,
57-
// tls_get_addr can call into malloc, which can create a recursive loop
58-
// instead we call pthread APIs to control the creation of TLS objects
59-
pthread_once(&_key_once, make_key);
60-
auto *tl_state = static_cast<TrackerThreadLocalState *>(
61-
pthread_getspecific(_tl_state_key));
62-
return tl_state;
63+
return static_cast<TrackerThreadLocalState *>(ddprof_lib_state);
6364
}
6465

6566
TrackerThreadLocalState *AllocationTracker::init_tl_state() {
@@ -69,13 +70,7 @@ TrackerThreadLocalState *AllocationTracker::init_tl_state() {
6970
auto tl_state = std::make_unique<TrackerThreadLocalState>();
7071
tl_state->tid = ddprof::gettid();
7172
tl_state->stack_bounds = retrieve_stack_bounds();
72-
73-
if (int const res = pthread_setspecific(_tl_state_key, tl_state.get());
74-
res != 0) {
75-
// should return 0
76-
LG_DBG("Unable to store tl_state. Error %d: %s\n", res, strerror(res));
77-
tl_state.reset();
78-
}
73+
ddprof_lib_state = tl_state.get();
7974

8075
return tl_state.release();
8176
}
@@ -91,11 +86,6 @@ void AllocationTracker::delete_tl_state(void *tl_state) {
9186
delete static_cast<TrackerThreadLocalState *>(tl_state);
9287
}
9388

94-
void AllocationTracker::make_key() {
95-
// delete is called on all key objects
96-
pthread_key_create(&_tl_state_key, delete_tl_state);
97-
}
98-
9989
DDRes AllocationTracker::allocation_tracking_init(
10090
uint64_t allocation_profiling_rate, uint32_t flags,
10191
uint32_t stack_sample_size, const RingBufferInfo &ring_buffer,

src/lib/loader.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include <time.h>
1919
#include <unistd.h>
2020

21+
__attribute__((__visibility__("default")))
22+
__attribute__((tls_model("initial-exec"))) __thread void *ddprof_lib_state;
23+
2124
/* Role of loader is to ensure that all dependencies (libdl/lim/libpthread) of
2225
* libdd_profiling-embedded.so are satisfied before dlopen'ing it.
2326
* On musl, all libc features are in libc.so and hence are available once libc

0 commit comments

Comments
 (0)