diff --git a/ide/vs2017/mimalloc-override-test.vcxproj b/ide/vs2017/mimalloc-override-test.vcxproj
index c50f80dc..77752890 100644
--- a/ide/vs2017/mimalloc-override-test.vcxproj
+++ b/ide/vs2017/mimalloc-override-test.vcxproj
@@ -90,10 +90,18 @@
true
..\..\include
MultiThreadedDebugDLL
+ false
+ Default
+ false
Console
+ kernel32.lib;%(AdditionalDependencies)
+
+
+ COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath)
+
@@ -103,14 +111,20 @@
true
..\..\include
MultiThreadedDebugDLL
+ false
+ Default
+ false
Console
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
- false
+ kernel32.lib;%(AdditionalDependencies)
+
+
+ COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect.dll $(OutputPath)
+
@@ -128,7 +142,11 @@
true
true
Console
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+ COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath)
+
@@ -150,9 +168,21 @@
kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+ COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect.dll $(OutputPath)
+
-
+
+ true
+ true
+ true
+ true
+
+
+ false
+ false
+
diff --git a/ide/vs2017/mimalloc-override-test.vcxproj.filters b/ide/vs2017/mimalloc-override-test.vcxproj.filters
index eb5e70b7..80f1c9c0 100644
--- a/ide/vs2017/mimalloc-override-test.vcxproj.filters
+++ b/ide/vs2017/mimalloc-override-test.vcxproj.filters
@@ -18,5 +18,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/ide/vs2017/mimalloc-override.vcxproj b/ide/vs2017/mimalloc-override.vcxproj
index 5fe9f10e..5fad3cf1 100644
--- a/ide/vs2017/mimalloc-override.vcxproj
+++ b/ide/vs2017/mimalloc-override.vcxproj
@@ -70,21 +70,25 @@
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.dll
+ mimalloc
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.dll
+ mimalloc
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.dll
+ mimalloc
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.dll
+ mimalloc
@@ -96,6 +100,7 @@
MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;_MBCS;%(PreprocessorDefinitions);
MultiThreadedDebugDLL
false
+ Default
@@ -106,8 +111,7 @@
- DllEntry
- kernel32.lib;%(AdditionalDependencies)
+ ../../bin/mimalloc-redirect32.lib;%(AdditionalDependencies)
@@ -124,6 +128,7 @@
MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;_MBCS;%(PreprocessorDefinitions);
MultiThreadedDebugDLL
false
+ Default
@@ -134,8 +139,7 @@
- DllEntry
- kernel32.lib;%(AdditionalDependencies)
+ ../../bin/mimalloc-redirect.lib;%(AdditionalDependencies)
@@ -156,12 +160,12 @@
$(IntDir)
false
MultiThreadedDLL
+ Default
true
true
- DllEntry
- kernel32.lib;%(AdditionalDependencies)
+ ../../bin/mimalloc-redirect32.lib;%(AdditionalDependencies)
@@ -188,12 +192,12 @@
$(IntDir)
false
MultiThreadedDLL
+ Default
true
true
- DllEntry
- kernel32.lib;%(AdditionalDependencies)
+ ../../bin/mimalloc-redirect.lib;%(AdditionalDependencies)
@@ -219,7 +223,18 @@
false
false
-
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
diff --git a/ide/vs2017/mimalloc-override.vcxproj.filters b/ide/vs2017/mimalloc-override.vcxproj.filters
index d2892c32..a39667f3 100644
--- a/ide/vs2017/mimalloc-override.vcxproj.filters
+++ b/ide/vs2017/mimalloc-override.vcxproj.filters
@@ -46,9 +46,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -61,8 +58,14 @@
Source Files
+
+ Source Files
+
Source Files
+
+ Source Files
+
-
+
\ No newline at end of file
diff --git a/ide/vs2017/mimalloc.sln b/ide/vs2017/mimalloc.sln
index aeab6b88..f4860d93 100644
--- a/ide/vs2017/mimalloc.sln
+++ b/ide/vs2017/mimalloc.sln
@@ -11,8 +11,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimall
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -53,14 +51,6 @@ Global
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
- {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ide/vs2017/mimalloc.vcxproj b/ide/vs2017/mimalloc.vcxproj
index bb1818b0..4a2069c6 100644
--- a/ide/vs2017/mimalloc.vcxproj
+++ b/ide/vs2017/mimalloc.vcxproj
@@ -70,21 +70,25 @@
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.lib
+ mimalloc-static
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.lib
+ mimalloc-static
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.lib
+ mimalloc-static
$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\
$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\
.lib
+ mimalloc-static
diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h
index 3b45ada4..1d380e8f 100644
--- a/include/mimalloc-internal.h
+++ b/include/mimalloc-internal.h
@@ -35,6 +35,7 @@ bool _mi_is_main_thread(void);
uintptr_t _mi_ptr_cookie(const void* p);
uintptr_t _mi_random_shuffle(uintptr_t x);
uintptr_t _mi_random_init(uintptr_t seed /* can be zero */);
+bool _mi_preloading(); // true while the C runtime is not ready
// os.c
size_t _mi_os_page_size(void);
diff --git a/include/mimalloc.h b/include/mimalloc.h
index 3c10a65b..9828a6bb 100644
--- a/include/mimalloc.h
+++ b/include/mimalloc.h
@@ -197,6 +197,7 @@ mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_b
mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;
+
// ------------------------------------------------------
// Convenience
// ------------------------------------------------------
@@ -245,14 +246,15 @@ mi_decl_export void mi_option_set(mi_option_t option, long value);
mi_decl_export void mi_option_set_default(mi_option_t option, long value);
-// ----------------------------------------------------------------------------------
-// mi prefixed implementations of various posix, unix, and C++ allocation functions.
-// -----------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------------------
+// mi prefixed implementations of various posix, Unix, Windows, and C++ allocation functions.
+// (This can be convenient when providing overrides of these functions.)
+// --------------------------------------------------------------------------------------------
-mi_decl_export void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept;
mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept;
mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
+mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept;
mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
mi_decl_export int mi__posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
@@ -263,6 +265,10 @@ mi_decl_export mi_decl_allocator void* mi_pvalloc(size_t size) mi_attr_noexcept
mi_decl_export mi_decl_allocator void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
mi_decl_export mi_decl_allocator void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3);
+mi_decl_export void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept;
+mi_decl_export void* mi_aligned_recalloc(void* p, size_t size, size_t newcount, size_t alignment) mi_attr_noexcept;
+mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t size, size_t newcount, size_t alignment, size_t offset) mi_attr_noexcept;
+
mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept;
mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept;
mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept;
diff --git a/src/alloc-aligned.c b/src/alloc-aligned.c
index 3ef93c83..175fa3e3 100644
--- a/src/alloc-aligned.c
+++ b/src/alloc-aligned.c
@@ -150,3 +150,14 @@ void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t of
void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
return mi_heap_realloc_aligned(mi_get_default_heap(), p, newsize, alignment);
}
+
+void* mi_aligned_offset_recalloc(void* p, size_t size, size_t newcount, size_t alignment, size_t offset) mi_attr_noexcept {
+ size_t newsize;
+ if (mi_mul_overflow(size,newcount,&newsize)) return NULL;
+ return mi_heap_realloc_zero_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset, true );
+}
+void* mi_aligned_recalloc(void* p, size_t size, size_t newcount, size_t alignment) mi_attr_noexcept {
+ size_t newsize;
+ if (mi_mul_overflow(size, newcount, &newsize)) return NULL;
+ return mi_heap_realloc_zero_aligned(mi_get_default_heap(), p, newsize, alignment, true );
+}
diff --git a/src/alloc-override-win.c b/src/alloc-override-win.c
index f0a5959a..7b0fe69f 100644
--- a/src/alloc-override-win.c
+++ b/src/alloc-override-win.c
@@ -98,11 +98,6 @@ static int __cdecl mi_setmaxstdio(int newmax);
// Microsoft allocation extensions
// ------------------------------------------------------
-static void* mi__expand(void* p, size_t newsize) {
- void* res = mi_expand(p, newsize);
- if (res == NULL) errno = ENOMEM;
- return res;
-}
typedef size_t mi_nothrow_t;
diff --git a/src/alloc-override.c b/src/alloc-override.c
index 5ca88af7..5378850b 100644
--- a/src/alloc-override.c
+++ b/src/alloc-override.c
@@ -194,4 +194,5 @@ int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_me
#pragma GCC visibility pop
#endif
-#endif // MI_MALLOC_OVERRIDE & !_WIN32
+#endif // MI_MALLOC_OVERRIDE && !_WIN32
+
diff --git a/src/alloc-posix.c b/src/alloc-posix.c
index b3185f15..3d28f655 100644
--- a/src/alloc-posix.c
+++ b/src/alloc-posix.c
@@ -80,3 +80,14 @@ void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept {
return newp;
}
+void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft
+ void* res = mi_expand(p, newsize);
+ if (res == NULL) errno = ENOMEM;
+ return res;
+}
+
+void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { // Microsoft
+ size_t total;
+ if (mi_mul_overflow(count, size, &total)) return NULL;
+ return _mi_heap_realloc_zero(mi_get_default_heap(), p, total, true);
+}
diff --git a/src/alloc.c b/src/alloc.c
index da8c69b9..10a74ce3 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -393,12 +393,6 @@ void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {
return mi_heap_realloc(mi_get_default_heap(),p,newsize);
}
-void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {
- size_t total;
- if (mi_mul_overflow(count, size, &total)) return NULL;
- return _mi_heap_realloc_zero(mi_get_default_heap(),p,total,true);
-}
-
void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {
return mi_heap_reallocn(mi_get_default_heap(),p,count,size);
}
@@ -537,6 +531,7 @@ std_new_handler_t mi_get_new_handler() {
return _ZSt15get_new_handlerv();
}
#else
+// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`.
std_new_handler_t mi_get_new_handler() {
return NULL;
}
diff --git a/src/heap.c b/src/heap.c
index 2b7b7a99..48bb9830 100644
--- a/src/heap.c
+++ b/src/heap.c
@@ -172,7 +172,7 @@ void mi_collect(bool force) mi_attr_noexcept {
----------------------------------------------------------- */
mi_heap_t* mi_heap_get_default(void) {
- mi_thread_init();
+ // mi_thread_init();
return mi_get_default_heap();
}
diff --git a/src/init.c b/src/init.c
index f55b7318..06aa28c5 100644
--- a/src/init.c
+++ b/src/init.c
@@ -373,6 +373,47 @@ void mi_thread_done(void) mi_attr_noexcept {
// --------------------------------------------------------
static void mi_process_done(void);
+static bool os_preloading = true; // true until this module is initialized
+static bool mi_redirected = false; // true if malloc redirects to mi_malloc
+
+// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false.
+bool _mi_preloading() {
+ return os_preloading;
+}
+
+// Communicate with the redirection module on Windows
+#if defined(_WIN32) && defined(MI_SHARED_LIB)
+mi_decl_export void _mi_redirect_init() {
+ // called on redirection
+ mi_redirected = true;
+}
+__declspec(dllimport) bool mi_allocator_init(const char** message);
+__declspec(dllimport) void mi_allocator_done();
+#else
+static bool mi_allocator_init(const char** message) {
+ if (message != NULL) *message = NULL;
+ return true;
+}
+static void mi_allocator_done() {
+ // nothing to do
+}
+#endif
+
+// Called once by the process loader
+static void mi_process_load(void) {
+ os_preloading = false;
+ atexit(&mi_process_done);
+ mi_process_init();
+ //mi_stats_reset();
+ if (mi_redirected) _mi_verbose_message("malloc is redirected.\n");
+
+ // show message from the redirector (if present)
+ const char* msg = NULL;
+ mi_allocator_init(&msg);
+ if (msg != NULL) _mi_verbose_message(msg);
+}
+
+// Initialize the process; called by thread_init or the process loader
void mi_process_init(void) mi_attr_noexcept {
// ensure we are called once
if (_mi_process_is_initialized) return;
@@ -381,7 +422,7 @@ void mi_process_init(void) mi_attr_noexcept {
// when using dynamic linking with interpose.
mi_heap_t* h = _mi_heap_default;
_mi_process_is_initialized = true;
-
+
_mi_heap_main.thread_id = _mi_thread_id();
_mi_verbose_message("process init: 0x%zx\n", _mi_heap_main.thread_id);
uintptr_t random = _mi_random_init(_mi_heap_main.thread_id) ^ (uintptr_t)h;
@@ -389,15 +430,16 @@ void mi_process_init(void) mi_attr_noexcept {
_mi_heap_main.cookie = (uintptr_t)&_mi_heap_main ^ random;
#endif
_mi_heap_main.random = _mi_random_shuffle(random);
+ mi_process_setup_auto_thread_done();
+ _mi_os_init();
#if (MI_DEBUG)
_mi_verbose_message("debug level : %d\n", MI_DEBUG);
#endif
- atexit(&mi_process_done);
- mi_process_setup_auto_thread_done();
- mi_stats_reset();
- _mi_os_init();
+ mi_thread_init();
+ mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL)
}
+// Called when the process is done (through `at_exit`)
static void mi_process_done(void) {
// only shutdown if we were initialized
if (!_mi_process_is_initialized) return;
@@ -413,7 +455,9 @@ static void mi_process_done(void) {
mi_option_is_enabled(mi_option_verbose)) {
mi_stats_print(NULL);
}
+ mi_allocator_done();
_mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id);
+ os_preloading = true; // don't call the C runtime anymore
}
@@ -425,8 +469,8 @@ static void mi_process_done(void) {
__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {
UNUSED(reserved);
UNUSED(inst);
- if (reason==DLL_PROCESS_ATTACH) {
- mi_process_init();
+ if (reason==DLL_PROCESS_ATTACH) {
+ mi_process_load();
}
else if (reason==DLL_THREAD_DETACH) {
mi_thread_done();
@@ -437,7 +481,7 @@ static void mi_process_done(void) {
#elif defined(__cplusplus)
// C++: use static initialization to detect process start
static bool _mi_process_init(void) {
- mi_process_init();
+ mi_process_load();
return (_mi_heap_main.thread_id != 0);
}
static bool mi_initialized = _mi_process_init();
@@ -445,14 +489,14 @@ static void mi_process_done(void) {
#elif defined(__GNUC__) || defined(__clang__)
// GCC,Clang: use the constructor attribute
static void __attribute__((constructor)) _mi_process_init(void) {
- mi_process_init();
+ mi_process_load();
}
#elif defined(_MSC_VER)
// MSVC: use data section magic for static libraries
// See
static int _mi_process_init(void) {
- mi_process_init();
+ mi_process_load();
return 0;
}
typedef int(*_crt_cb)(void);
@@ -467,5 +511,5 @@ static void mi_process_done(void) {
#pragma data_seg()
#else
-#pragma message("define a way to call mi_process_init/done on your platform")
+#pragma message("define a way to call mi_process_load on your platform")
#endif
diff --git a/src/memory.c b/src/memory.c
index 83e90b0d..74a9628c 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -114,6 +114,7 @@ bool mi_is_in_heap_region(const void* p) {
return false;
}
+
/* ----------------------------------------------------------------------------
Commit from a region
-----------------------------------------------------------------------------*/
diff --git a/src/options.c b/src/options.c
index ac0910a0..36997d80 100644
--- a/src/options.c
+++ b/src/options.c
@@ -16,6 +16,10 @@ int mi_version(void) mi_attr_noexcept {
return MI_MALLOC_VERSION;
}
+#ifdef _WIN32
+#include
+#endif
+
// --------------------------------------------------------
// Options
// --------------------------------------------------------
@@ -31,7 +35,7 @@ typedef struct mi_option_desc_s {
const char* name; // option name without `mimalloc_` prefix
} mi_option_desc_t;
-static mi_option_desc_t options[_mi_option_last] =
+static mi_option_desc_t options[_mi_option_last] =
{
// stable options
{ 0, UNINIT, "show_stats" },
@@ -41,15 +45,15 @@ static mi_option_desc_t options[_mi_option_last] =
// the following options are experimental and not all combinations make sense.
{ 0, UNINIT, "page_reset" },
{ 0, UNINIT, "cache_reset" },
- { 1, UNINIT, "eager_commit" },
- { 1, UNINIT, "eager_region_commit" }, // eager_commit should be on when eager_region_commit is on
+ { 1, UNINIT, "eager_commit" },
+ { 1, UNINIT, "eager_region_commit" }, // eager_commit should be on when eager_region_commit is on
{ 0, UNINIT, "large_os_pages" }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's
- { 0, UNINIT, "reset_decommits" },
- { 0, UNINIT, "reset_discards" },
+ { 0, UNINIT, "reset_decommits" },
+ { 0, UNINIT, "reset_discards" },
#if MI_SECURE
{ MI_SECURE, INITIALIZED, "secure" } // in a secure build the environment setting is ignored
#else
- { 0, UNINIT, "secure" }
+ { 0, UNINIT, "secure" }
#endif
};
@@ -104,7 +108,17 @@ static void mi_vfprintf( FILE* out, const char* prefix, const char* fmt, va_list
char buf[256];
if (fmt==NULL) return;
if (out==NULL) out = stdout;
+ if (_mi_preloading()) return;
vsnprintf(buf,sizeof(buf)-1,fmt,args);
+ #ifdef _WIN32
+ // on windows with redirection, the C runtime uses us and we cannot call `fputs`
+ // while called from the C runtime itself, so use a non-locking option
+ if (out==stderr) {
+ if (prefix != NULL) _cputs(prefix);
+ _cputs(buf);
+ return;
+ }
+ #endif
if (prefix != NULL) fputs(prefix,out);
fputs(buf,out);
}
@@ -174,21 +188,29 @@ static void mi_strlcat(char* dest, const char* src, size_t dest_size) {
dest[dest_size - 1] = 0;
}
-static void mi_option_init(mi_option_desc_t* desc) {
- desc->init = DEFAULTED;
- // Read option value from the environment
- char buf[32];
- mi_strlcpy(buf, "mimalloc_", sizeof(buf));
- mi_strlcat(buf, desc->name, sizeof(buf));
+static const char* mi_getenv(const char* name) {
+ if (_mi_preloading()) return NULL; // don't call getenv too early
#pragma warning(suppress:4996)
- char* s = getenv(buf);
+ const char* s = getenv(name);
if (s == NULL) {
+ char buf[64+1];
+ strncpy_s(buf,64,name,64); buf[64] = 0;
for (size_t i = 0; i < strlen(buf); i++) {
- buf[i] = toupper(buf[i]);
+ buf[i] = toupper(name[i]);
}
#pragma warning(suppress:4996)
s = getenv(buf);
}
+ return s;
+}
+
+static void mi_option_init(mi_option_desc_t* desc) {
+ if (!_mi_preloading()) desc->init = DEFAULTED;
+ // Read option value from the environment
+ char buf[64];
+ mi_strlcpy(buf, "mimalloc_", sizeof(buf));
+ mi_strlcat(buf, desc->name, sizeof(buf));
+ const char* s = mi_getenv(buf);
if (s != NULL) {
mi_strlcpy(buf, s, sizeof(buf));
for (size_t i = 0; i < strlen(buf); i++) {
diff --git a/test/main-override.c b/test/main-override.c
index 836ea58d..ddb2f16e 100644
--- a/test/main-override.c
+++ b/test/main-override.c
@@ -3,30 +3,29 @@
#include
#include
-#include
+//#include
int main() {
- mi_stats_reset();
+ //mi_stats_reset();
void* p1 = malloc(78);
void* p2 = malloc(24);
free(p1);
p1 = malloc(8);
- char* s = strdup("hello\n");
+ //char* s = strdup("hello\n");
free(p2);
p2 = malloc(16);
p1 = realloc(p1, 32);
free(p1);
free(p2);
- free(s);
- mi_collect(true);
+ //free(s);
+ //mi_collect(true);
/* now test if override worked by allocating/freeing across the api's*/
- p1 = mi_malloc(32);
- free(p1);
- p2 = malloc(32);
- mi_free(p2);
+ //p1 = mi_malloc(32);
+ //free(p1);
+ //p2 = malloc(32);
+ //mi_free(p2);
- mi_stats_print(NULL);
return 0;
}
diff --git a/test/main-override.cpp b/test/main-override.cpp
index 3f2bc960..3c192fe3 100644
--- a/test/main-override.cpp
+++ b/test/main-override.cpp
@@ -4,6 +4,7 @@
#include
#include
+#include
#include
@@ -22,15 +23,17 @@ public:
~Test() { }
};
-int main() {
- mi_stats_reset();
+
+int main() {
+ //mi_malloc_override();
+ mi_stats_reset();
atexit(free_p);
void* p1 = malloc(78);
- void* p2 = malloc(24);
+ void* p2 = _aligned_malloc(24,16);
free(p1);
p1 = malloc(8);
- char* s = mi_strdup("hello\n");
- free(p2);
+ char* s = _strdup("hello\n");
+ _aligned_free(p2);
p2 = malloc(16);
p1 = realloc(p1, 32);
free(p1);
@@ -40,12 +43,8 @@ int main() {
delete t;
t = new (std::nothrow) Test(42);
delete t;
- int err = mi_posix_memalign(&p1,32,60);
- if (!err) free(p1);
free(p);
- mi_collect(true);
- mi_stats_print(NULL); // MIMALLOC_VERBOSE env is set to 2
- return 0;
+ return 0;
}
class Static {