From 0ae310327f83abd3b354bf03b819f3595be0daf2 Mon Sep 17 00:00:00 2001 From: Daan Date: Tue, 13 May 2025 16:22:08 -0700 Subject: [PATCH 1/3] fix debug assertion for windows TLS --- src/prim/windows/prim.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/prim/windows/prim.c b/src/prim/windows/prim.c index 535d34a6..6ab715e6 100644 --- a/src/prim/windows/prim.c +++ b/src/prim/windows/prim.c @@ -644,12 +644,12 @@ static void mi_win_tls_init(DWORD reason) { #endif if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) { if (mi_prim_get_default_heap() == NULL) { - _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty); + _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty); + #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1 + void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*))); + mi_assert_internal(p == (void*)&_mi_heap_empty); + #endif } - #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1 - void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*))); - mi_assert_internal(p == (void*)&_mi_heap_empty); - #endif } #else MI_UNUSED(reason); From df3e1916209b3783bb3d001013ce8fbba4815da6 Mon Sep 17 00:00:00 2001 From: Daan Date: Tue, 13 May 2025 16:38:53 -0700 Subject: [PATCH 2/3] make windows fixed TLS opt-in --- include/mimalloc/prim.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/mimalloc/prim.h b/include/mimalloc/prim.h index d3157949..fbf0cc74 100644 --- a/include/mimalloc/prim.h +++ b/include/mimalloc/prim.h @@ -118,9 +118,6 @@ void _mi_prim_thread_done_auto_done(void); void _mi_prim_thread_associate_default_heap(mi_heap_t* heap); - -#define MI_WIN_USE_FIXED_TLS 1 - //------------------------------------------------------------------- // Access to TLS (thread local storage) slots. // We need fast access to both a unique thread id (in `free.c:mi_free`) and From 41cc1bfe5199fbfc4dc5e7c7ecb1453ad4e8ad7b Mon Sep 17 00:00:00 2001 From: daanx Date: Tue, 13 May 2025 17:38:16 -0700 Subject: [PATCH 3/3] add guarded TLS test for Windows fixed TLS --- ide/vs2022/mimalloc-test-stress.vcxproj | 4 +-- include/mimalloc/prim.h | 2 +- src/init.c | 1 - src/prim/windows/prim.c | 33 ++++++++++++++----------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/ide/vs2022/mimalloc-test-stress.vcxproj b/ide/vs2022/mimalloc-test-stress.vcxproj index d6af71ce..128a4ff6 100644 --- a/ide/vs2022/mimalloc-test-stress.vcxproj +++ b/ide/vs2022/mimalloc-test-stress.vcxproj @@ -282,8 +282,8 @@ - - {abb5eae7-b3e6-432e-b636-333449892ea6} + + {abb5eae7-b3e6-432e-b636-333449892ea7} diff --git a/include/mimalloc/prim.h b/include/mimalloc/prim.h index fbf0cc74..3d8f1806 100644 --- a/include/mimalloc/prim.h +++ b/include/mimalloc/prim.h @@ -208,7 +208,7 @@ static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexce // thread-local initialization checks in the fast path. // We allocate a user TLS slot at process initialization (see `windows/prim.c`) // and store the offset `_mi_win_tls_offset`. -#define MI_HAS_TLS_SLOT 2 // 2 = we can reliably initialize the slot (saving a test on each malloc) +#define MI_HAS_TLS_SLOT 1 // 2 = we can reliably initialize the slot (saving a test on each malloc) extern mi_decl_hidden size_t _mi_win_tls_offset; diff --git a/src/init.c b/src/init.c index fe0acd8a..ff6c5d29 100644 --- a/src/init.c +++ b/src/init.c @@ -225,7 +225,6 @@ mi_heap_t* _mi_heap_main_get(void) { return &_mi_heap_main; } - /* ----------------------------------------------------------- Sub process ----------------------------------------------------------- */ diff --git a/src/prim/windows/prim.c b/src/prim/windows/prim.c index 6ab715e6..9ffacaa3 100644 --- a/src/prim/windows/prim.c +++ b/src/prim/windows/prim.c @@ -631,18 +631,23 @@ bool _mi_prim_random_buf(void* buf, size_t buf_len) { mi_decl_cache_align size_t _mi_win_tls_offset = 0; #endif +//static void mi_debug_out(const char* s) { +// HANDLE h = GetStdHandle(STD_ERROR_HANDLE); +// WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL); +//} + static void mi_win_tls_init(DWORD reason) { - #if MI_HAS_TLS_SLOT >= 2 // we must initialize the TLS slot before any allocation - #if MI_WIN_USE_FIXED_TLS==1 - if (reason==DLL_PROCESS_ATTACH && _mi_win_tls_offset == 0) { - const DWORD tls_slot = TlsAlloc(); // usually returns slot 1 - if (tls_slot == TLS_OUT_OF_INDEXES) { - _mi_error_message(EFAULT, "unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n"); - } - _mi_win_tls_offset = (size_t)tls_slot * sizeof(void*); - } - #endif if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) { + #if MI_WIN_USE_FIXED_TLS==1 // we must allocate a TLS slot dynamically + if (_mi_win_tls_offset == 0 && reason=DLL_PROCESS_ATTACH) { + const DWORD tls_slot = TlsAlloc(); // usually returns slot 1 + if (tls_slot == TLS_OUT_OF_INDEXES) { + _mi_error_message(EFAULT, "unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n"); + } + _mi_win_tls_offset = (size_t)tls_slot * sizeof(void*); + } + #endif + #if MI_HAS_TLS_SLOT >= 2 // we must initialize the TLS slot before any allocation if (mi_prim_get_default_heap() == NULL) { _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty); #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1 @@ -650,10 +655,8 @@ static void mi_win_tls_init(DWORD reason) { mi_assert_internal(p == (void*)&_mi_heap_empty); #endif } - } - #else - MI_UNUSED(reason); - #endif + #endif + } } static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) { @@ -676,7 +679,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) { #define MI_PRIM_HAS_PROCESS_ATTACH 1 // Windows DLL: easy to hook into process_init and thread_done - BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { + BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { mi_win_main((PVOID)inst,reason,reserved); return TRUE; }