Skip to content

Commit c4c11c3

Browse files
[libc] add _malloc_thread_cleanup option
1 parent 531ff74 commit c4c11c3

File tree

6 files changed

+33
-0
lines changed

6 files changed

+33
-0
lines changed

libc/config/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
"LIBC_CONF_RWLOCK_DEFAULT_SPIN_COUNT": {
9090
"value": 100,
9191
"doc": "Default number of spins before blocking if a rwlock is in contention (default to 100)."
92+
},
93+
"LIBC_CONF_ENABLE_MALLOC_THREAD_CLEANUP": {
94+
"value": false,
95+
"doc": "Enable the `_malloc_thread_cleanup` weak symbol. When defined, this is function is called after `__cxa` and pthread-specific dtors. On main thread, this will be called after `atexit` functions and `.fini` dtors, right before TLS tearing down. This function can be overridden by allocators to perform cleanup. Allocators can use this symbol to avoid registering thread dtors using potentially reentrant routines."
9296
}
9397
},
9498
"math": {

libc/docs/configure.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ to learn about the defaults for your platform and target.
4747
- ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE``: Use large table for better printf long double performance.
4848
- ``LIBC_CONF_PRINTF_RUNTIME_DISPATCH``: Use dynamic dispatch for the output mechanism to reduce code size.
4949
* **"pthread" options**
50+
- ``LIBC_CONF_ENABLE_MALLOC_THREAD_CLEANUP``: Enable the `_malloc_thread_cleanup` weak symbol. When defined, this is function is called after `__cxa` and pthread-specific dtors. On main thread, this will be called after `atexit` functions and `.fini` dtors, right before TLS tearing down. This function can be overridden by allocators to perform cleanup. Allocators can use this symbol to avoid registering thread dtors using potentially reentrant routines.
5051
- ``LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT``: Default number of spins before blocking if a mutex is in contention (default to 100).
5152
- ``LIBC_CONF_RWLOCK_DEFAULT_SPIN_COUNT``: Default number of spins before blocking if a rwlock is in contention (default to 100).
5253
- ``LIBC_CONF_TIMEOUT_ENSURE_MONOTONICITY``: Automatically adjust timeout to CLOCK_MONOTONIC (default to true). POSIX API may require CLOCK_REALTIME, which can be unstable and leading to unexpected behavior. This option will convert the real-time timestamp to monotonic timestamp relative to the time of call.

libc/src/__support/threads/linux/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ add_header_library(
7171
libc.src.__support.threads.mutex_common
7272
)
7373

74+
if (LIBC_CONF_ENABLE_MALLOC_THREAD_CLEANUP)
75+
set(malloc_cleanup_flags -DLIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP)
76+
else()
77+
set(malloc_cleanup_flags)
78+
endif()
79+
7480
add_object_library(
7581
thread
7682
SRCS
@@ -89,6 +95,7 @@ add_object_library(
8995
libc.src.__support.threads.thread_common
9096
COMPILE_OPTIONS
9197
${libc_opt_high_flag}
98+
${malloc_cleanup_flags}
9299
-fno-omit-frame-pointer # This allows us to sniff out the thread args from
93100
# the new thread's stack reliably.
94101
-Wno-frame-address # Yes, calling __builtin_return_address with a

libc/src/__support/threads/linux/thread.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,10 @@ int Thread::get_name(cpp::StringStream &name) const {
482482
return 0;
483483
}
484484

485+
#ifdef LIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP
486+
extern "C" [[gnu::weak]] void _malloc_thread_cleanup();
487+
#endif // LIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP
488+
485489
void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
486490
auto attrib = self.attrib;
487491

@@ -494,6 +498,11 @@ void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
494498
// different thread. The destructors of thread local and TSS objects should
495499
// be called by the thread which owns them.
496500
internal::call_atexit_callbacks(attrib);
501+
#ifdef LIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP
502+
// call _malloc_thread_cleanup after the atexit callbacks
503+
if (_malloc_thread_cleanup)
504+
_malloc_thread_cleanup();
505+
#endif // LIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP
497506

498507
uint32_t joinable_state = uint32_t(DetachState::JOINABLE);
499508
if (!attrib->detach_state.compare_exchange_strong(

libc/src/stdlib/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,12 @@ add_header_library(
589589
)
590590
endif()
591591

592+
if (LIBC_CONF_ENABLE_MALLOC_THREAD_CLEANUP)
593+
set(malloc_cleanup_flags -DLIBC_COPT_ENABLE_MALLOC_THREAD_CLEANUP)
594+
else()
595+
set(malloc_cleanup_flags)
596+
endif()
597+
592598
add_entrypoint_object(
593599
atexit
594600
SRCS
@@ -599,6 +605,8 @@ add_entrypoint_object(
599605
20 # For constinit
600606
DEPENDS
601607
.exit_handler
608+
COMPILE_OPTIONS
609+
${malloc_cleanup_flags}
602610
)
603611

604612
add_entrypoint_object(

libc/src/stdlib/atexit.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ constinit ExitCallbackList atexit_callbacks;
1818
Mutex handler_list_mtx(false, false, false, false);
1919
[[gnu::weak]] extern void teardown_main_tls();
2020

21+
namespace internal {
22+
[[gnu::weak]] extern void call_atexit_callbacks();
23+
}
24+
2125
extern "C" {
2226

2327
int __cxa_atexit(AtExitCallback *callback, void *payload, void *) {

0 commit comments

Comments
 (0)