diff --git a/include/mimalloc/prim.h b/include/mimalloc/prim.h index 8e94796f..7fbeef2a 100644 --- a/include/mimalloc/prim.h +++ b/include/mimalloc/prim.h @@ -209,20 +209,19 @@ static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexce #elif _WIN32 && MI_WIN_USE_FIXED_TLS && !defined(MI_WIN_USE_FLS) // On windows we can store the thread-local heap at a fixed TLS slot to avoid -// thread-local initialization checks in the fast path. -// We always use the second user TLS slot (the first one is always allocated already), -// and at initialization (`windows/prim.c`) we call TlsAlloc and verify -// we indeed get the second slot (and fail otherwise). -// Todo: we could make the Tls slot completely dynamic but that would require -// an extra read of the static Tls slot instead of using a constant offset. +// thread-local initialization checks in the fast path. This uses a fixed location +// in the TCB though (last user-reserved slot by default) which may clash with other applications. + #define MI_HAS_TLS_SLOT 2 // 2 = we can reliably initialize the slot (saving a test on each malloc) #if MI_WIN_USE_FIXED_TLS > 1 #define MI_TLS_SLOT (MI_WIN_USE_FIXED_TLS) #elif MI_SIZE_SIZE == 4 -#define MI_TLS_SLOT (0x0E18) // Second User TLS slot +#define MI_TLS_SLOT (0x710) // Last user-reserved slot +// #define MI_TLS_SLOT (0xF0C) // Last TlsSlot (might clash with other app reserved slot) #else -#define MI_TLS_SLOT (0x1488) // Second User TLS slot +#define MI_TLS_SLOT (0x888) // Last user-reserved slot +// #define MI_TLS_SLOT (0x1678) // Last TlsSlot (might clash with other app reserved slot) #endif static inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept { diff --git a/src/os.c b/src/os.c index fb9f670f..ef720862 100644 --- a/src/os.c +++ b/src/os.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Copyright (c) 2018-2025, Microsoft Research, Daan Leijen +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. @@ -172,8 +172,8 @@ static void mi_os_free_huge_os_pages(void* p, size_t size); static void mi_os_prim_free(void* addr, size_t size, size_t commit_size) { mi_assert_internal((size % _mi_os_page_size()) == 0); - if (addr == NULL) return; // || _mi_os_is_huge_reserved(addr) - int err = _mi_prim_free(addr, size); // allow size==0 (issue #1041) + if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr) + int err = _mi_prim_free(addr, size); if (err != 0) { _mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr); } diff --git a/src/prim/emscripten/prim.c b/src/prim/emscripten/prim.c index 6a78dab0..d3dcca93 100644 --- a/src/prim/emscripten/prim.c +++ b/src/prim/emscripten/prim.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Copyright (c) 2018-2025, Microsoft Research, Daan Leijen, Alon Zakai +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen, Alon Zakai This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. @@ -58,7 +58,7 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config) { extern void emmalloc_free(void*); int _mi_prim_free(void* addr, size_t size) { - if (size==0) return 0; + MI_UNUSED(size); emmalloc_free(addr); return 0; } diff --git a/src/prim/unix/prim.c b/src/prim/unix/prim.c index 6818dd84..542fba16 100644 --- a/src/prim/unix/prim.c +++ b/src/prim/unix/prim.c @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Copyright (c) 2018-2025, Microsoft Research, Daan Leijen +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. @@ -72,6 +72,7 @@ terms of the MIT license. A copy of the license can be found in the file #define MI_UNIX_LARGE_PAGE_SIZE (2*MI_MiB) // TODO: can we query the OS for this? + //------------------------------------------------------------------------------------ // Use syscalls for some primitives to allow for libraries that override open/read/close etc. // and do allocation themselves; using syscalls prevents recursion when mimalloc is @@ -187,7 +188,6 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config ) //--------------------------------------------- int _mi_prim_free(void* addr, size_t size ) { - if (size==0) return 0; bool err = (munmap(addr, size) == -1); return (err ? errno : 0); } @@ -223,8 +223,8 @@ static void* unix_mmap_prim_aligned(void* addr, size_t size, size_t try_alignmen void* p = NULL; #if defined(MAP_ALIGNED) // BSD if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { - size_t n = 0; - mi_bsr(try_alignment, &n); + size_t idx; + size_t n = mi_bsr(try_alignment, &idx); if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB p = unix_mmap_prim(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd); if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { diff --git a/src/prim/windows/prim.c b/src/prim/windows/prim.c index 96259040..574e5678 100644 --- a/src/prim/windows/prim.c +++ b/src/prim/windows/prim.c @@ -650,20 +650,8 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) { MI_UNUSED(reserved); MI_UNUSED(module); #if MI_TLS_SLOT >= 2 - if (reason==DLL_PROCESS_ATTACH) { - const DWORD tls_slot = TlsAlloc(); - if (tls_slot != 1) { - _mi_error_message(EFAULT, "unable to allocate the second TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n"); - } - } - 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); - } - #if MI_DEBUG - void* const p = TlsGetValue(1); - mi_assert_internal(p == (void*)&_mi_heap_empty); - #endif + if ((reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) && mi_prim_get_default_heap() == NULL) { + _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty); } #endif if (reason==DLL_PROCESS_ATTACH) { diff --git a/test/main-override-dep.cpp b/test/main-override-dep.cpp index 4f293e7b..edb57f1f 100644 --- a/test/main-override-dep.cpp +++ b/test/main-override-dep.cpp @@ -1,7 +1,6 @@ -// Issue #981: test overriding allocation in a DLL that is compiled independent of mimalloc. +// Issue #981: test overriding allocation in a DLL that is compiled independent of mimalloc. // This is imported by the `mimalloc-test-override` project. #include -#include #include "main-override-dep.h" std::string TestAllocInDll::GetString() @@ -11,7 +10,6 @@ std::string TestAllocInDll::GetString() const char* t = "test"; memcpy(test, t, 4); std::string r = test; - std::cout << "override-dep: GetString: " << r << "\n"; delete[] test; return r; } @@ -24,37 +22,4 @@ void TestAllocInDll::TestHeapAlloc() int* p = (int*)HeapAlloc(heap, 0, sizeof(int)); *p = 42; HeapFree(heap, 0, p); -} - -class Static { -private: - void* p; -public: - Static() { - printf("override-dep: static constructor\n"); - p = malloc(64); - return; - } - ~Static() { - free(p); - printf("override-dep: static destructor\n"); - return; - } -}; - -static Static s = Static(); - - -#include - -BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID reserved) { - (void)(reserved); - (void)(module); - if (reason==DLL_PROCESS_ATTACH) { - printf("override-dep: dll attach\n"); - } - else if (reason==DLL_PROCESS_DETACH) { - printf("override-dep: dll detach\n"); - } - return TRUE; -} +} \ No newline at end of file diff --git a/test/main-override.cpp b/test/main-override.cpp index 408b5ee8..af385992 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -150,7 +150,7 @@ static void test_dep() { TestAllocInDll t; std::string s = t.GetString(); - std::cout << "test_dep GetString: " << s << "\n"; + t.TestHeapAlloc(); } #endif