diff --git a/src/foundation/compat_thread.c b/src/foundation/compat_thread.c index b76bdbd7f..d9922f510 100644 --- a/src/foundation/compat_thread.c +++ b/src/foundation/compat_thread.c @@ -7,10 +7,6 @@ #include "foundation/constants.h" #include "foundation/compat_thread.h" -#include "foundation/platform.h" - -#include /* mi_thread_done at thread exit */ - #include #include @@ -28,50 +24,6 @@ typedef struct { void *arg; } win_thread_arg_t; -/* Release each thread's allocator heap at DLL_THREAD_DETACH. - * - * Doing this from the thread wrapper instead crashes: the wrapper returns - * before the CRT's own thread teardown, and abandoning the heap there raced - * with frees still in flight (daemon_ipc_wait_forever_is_interruptible - * segfaulted, rc=139, reproducibly and only with the release enabled). A TLS - * callback is the mechanism mimalloc itself uses under MSVC and runs after all - * other thread cleanup, which is the only point where the heap is genuinely - * unreferenced. - * - * Without any of this, a static MinGW link -- no DllMain, no TLS callback -- - * never releases a thread heap at all: 607 heaps after 300 requests, 170 MiB - * held against a ~300 KiB live set, growing without bound (#581). POSIX gets - * this from a pthread TSD destructor, which is why only Windows leaked. - * - * CBM_MI_THREAD_DONE=0 disables it, so one binary can demonstrate both - * behaviours rather than requiring a rebuild to establish causality. */ -static bool thread_release_heap_enabled(void) { - static int state = -1; - if (state < 0) { - char buf[CBM_SZ_16]; - state = - (cbm_safe_getenv("CBM_MI_THREAD_DONE", buf, sizeof(buf), NULL) != NULL && buf[0] == '0') - ? 0 - : 1; - } - return state == 1; -} - -static void NTAPI cbm_thread_detach_callback(PVOID handle, DWORD reason, PVOID reserved) { - (void)handle; - (void)reserved; - if (reason == DLL_THREAD_DETACH && thread_release_heap_enabled()) { - mi_thread_done(); - } -} - -/* Park the callback in .CRT$XLB, the table the loader walks. The linker only - * emits a TLS directory when _tls_used is referenced, so anchor it. */ -extern const IMAGE_TLS_DIRECTORY64 _tls_used; -static const void *const cbm_tls_anchor __attribute__((used)) = &_tls_used; -__attribute__((section(".CRT$XLB"), used)) PIMAGE_TLS_CALLBACK cbm_thread_detach_tls_cb = - cbm_thread_detach_callback; - static DWORD WINAPI win_thread_wrapper(LPVOID lpParam) { win_thread_arg_t *a = (win_thread_arg_t *)lpParam; void *(*fn)(void *) = a->fn;