diff --git a/include/mimalloc.h b/include/mimalloc.h index f63038e5..194edb47 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -114,10 +114,8 @@ mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_fre typedef void (mi_output_fun)(const char* msg); mi_decl_export void mi_register_output(mi_output_fun* out) mi_attr_noexcept; -#if MI_USER_CLEANUP typedef void (mi_cleanup_fun)(void* user_data, void* p, size_t size); -mi_decl_export void mi_register_user_cleanup(mi_cleanup_fun* out, void* user_data) mi_attr_noexcept; -#endif +mi_decl_export void mi_register_user_cleanup(mi_cleanup_fun* cleanup, void* user_data) mi_attr_noexcept; mi_decl_export void mi_collect(bool force) mi_attr_noexcept; mi_decl_export int mi_version(void) mi_attr_noexcept; diff --git a/src/os.c b/src/os.c index 2ad0648f..4d08c7bd 100644 --- a/src/os.c +++ b/src/os.c @@ -177,6 +177,39 @@ void _mi_os_init() { } #endif +#if MI_USER_CLEANUP +static mi_cleanup_fun* user_cleanup = NULL; +static void* cleanup_udata = NULL; +static void _mi_call_user_cleanup(void* p, size_t size) +{ + if(user_cleanup) + user_cleanup(cleanup_udata, p, size); +#if (MI_DEBUG>1) + else + memset(start, 0, csize); +#endif +} +#else +static void _mi_call_user_cleanup(void* p, size_t size) +{ + (void)p; + (void)size; +#if (MI_DEBUG>1) + if (MI_SECURE==0) + memset(start, 0, csize); // pretend it is eagerly reset +#endif +} +#endif + +void mi_register_user_cleanup(mi_cleanup_fun* cleanup, void* user_data) +{ + (void)cleanup; + (void)user_data; +#if MI_USER_CLEANUP + user_cleanup = cleanup; + cleanup_udata = user_data; +#endif +} /* ----------------------------------------------------------- Raw allocation on Windows (VirtualAlloc) and Unix's (mmap). @@ -186,6 +219,7 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats { if (addr == NULL || size == 0 || _mi_os_is_huge_reserved(addr)) return true; bool err = false; + _mi_call_user_cleanup(addr, size); #if defined(_WIN32) err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); #elif defined(__wasi__) @@ -687,11 +721,7 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats) else _mi_stat_decrease(&stats->reset, csize); if (!reset) return true; // nothing to do on unreset! - #if (MI_DEBUG>1) - if (MI_SECURE==0) { - memset(start, 0, csize); // pretend it is eagerly reset - } - #endif + _mi_call_user_cleanup(start, size); #if defined(_WIN32) // Testing shows that for us (on `malloc-large`) MEM_RESET is 2x faster than DiscardVirtualMemory