mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-27 13:33:18 +08:00
experimental destroy_on_exit option for statically linked mimalloc in a dynamically unloaded DLL
This commit is contained in:
parent
18cf94dff6
commit
35d332141d
@ -139,6 +139,7 @@ uint8_t _mi_bin(size_t size); // for stats
|
|||||||
void _mi_heap_destroy_pages(mi_heap_t* heap);
|
void _mi_heap_destroy_pages(mi_heap_t* heap);
|
||||||
void _mi_heap_collect_abandon(mi_heap_t* heap);
|
void _mi_heap_collect_abandon(mi_heap_t* heap);
|
||||||
void _mi_heap_set_default_direct(mi_heap_t* heap);
|
void _mi_heap_set_default_direct(mi_heap_t* heap);
|
||||||
|
void _mi_heap_destroy_all(void);
|
||||||
|
|
||||||
// "stats.c"
|
// "stats.c"
|
||||||
void _mi_stats_done(mi_stats_t* stats);
|
void _mi_stats_done(mi_stats_t* stats);
|
||||||
|
@ -335,6 +335,7 @@ typedef enum mi_option_e {
|
|||||||
mi_option_max_errors,
|
mi_option_max_errors,
|
||||||
mi_option_max_warnings,
|
mi_option_max_warnings,
|
||||||
mi_option_max_segment_reclaim,
|
mi_option_max_segment_reclaim,
|
||||||
|
mi_option_destroy_on_exit,
|
||||||
_mi_option_last
|
_mi_option_last
|
||||||
} mi_option_t;
|
} mi_option_t;
|
||||||
|
|
||||||
|
15
src/heap.c
15
src/heap.c
@ -327,7 +327,20 @@ void mi_heap_destroy(mi_heap_t* heap) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _mi_heap_destroy_all(void) {
|
||||||
|
mi_heap_t* bheap = mi_heap_get_backing();
|
||||||
|
mi_heap_t* curr = bheap->tld->heaps;
|
||||||
|
while (curr != NULL) {
|
||||||
|
mi_heap_t* next = curr->next;
|
||||||
|
if (curr->no_reclaim) {
|
||||||
|
mi_heap_destroy(curr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mi_heap_destroy_pages(curr);
|
||||||
|
}
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
Safe Heap delete
|
Safe Heap delete
|
||||||
|
@ -598,7 +598,7 @@ static void mi_cdecl mi_process_done(void) {
|
|||||||
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
||||||
FlsFree(mi_fls_key); // call thread-done on all threads (except the main thread) to prevent dangling callback pointer if statically linked with a DLL; Issue #208
|
FlsFree(mi_fls_key); // call thread-done on all threads (except the main thread) to prevent dangling callback pointer if statically linked with a DLL; Issue #208
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MI_SKIP_COLLECT_ON_EXIT
|
#ifndef MI_SKIP_COLLECT_ON_EXIT
|
||||||
#if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB)
|
#if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB)
|
||||||
// free all memory if possible on process exit. This is not needed for a stand-alone process
|
// free all memory if possible on process exit. This is not needed for a stand-alone process
|
||||||
@ -608,6 +608,11 @@ static void mi_cdecl mi_process_done(void) {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (mi_option_is_enabled(mi_option_destroy_on_exit)) {
|
||||||
|
_mi_heap_destroy_all(); // forcefully release all memory held by all heaps (of this thread only!)
|
||||||
|
_mi_mem_collect(&_mi_heap_main_get()->tld->os); // release all regions
|
||||||
|
}
|
||||||
|
|
||||||
if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
|
if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
|
||||||
mi_stats_print(NULL);
|
mi_stats_print(NULL);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@ static mi_option_desc_t options[_mi_option_last] =
|
|||||||
{ 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose
|
{ 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose
|
||||||
{ 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors that are output
|
{ 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors that are output
|
||||||
{ 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output
|
{ 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output
|
||||||
{ 8, UNINIT, MI_OPTION(max_segment_reclaim)} // max. number of segment reclaims from the abandoned segments per try.
|
{ 8, UNINIT, MI_OPTION(max_segment_reclaim)},// max. number of segment reclaims from the abandoned segments per try.
|
||||||
|
{ 0, UNINIT, MI_OPTION(destroy_on_exit)} // release all OS memory on process exit; careful with dangling pointer or after-exit frees!
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mi_option_init(mi_option_desc_t* desc);
|
static void mi_option_init(mi_option_desc_t* desc);
|
||||||
|
@ -32,7 +32,7 @@ int main() {
|
|||||||
// invalid_free();
|
// invalid_free();
|
||||||
// test_reserved();
|
// test_reserved();
|
||||||
// negative_stat();
|
// negative_stat();
|
||||||
test_heap_walk();
|
// test_heap_walk();
|
||||||
// alloc_huge();
|
// alloc_huge();
|
||||||
|
|
||||||
void* p1 = malloc(78);
|
void* p1 = malloc(78);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user