mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-26 21:04:27 +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_collect_abandon(mi_heap_t* heap);
|
||||
void _mi_heap_set_default_direct(mi_heap_t* heap);
|
||||
void _mi_heap_destroy_all(void);
|
||||
|
||||
// "stats.c"
|
||||
void _mi_stats_done(mi_stats_t* stats);
|
||||
|
@ -335,6 +335,7 @@ typedef enum mi_option_e {
|
||||
mi_option_max_errors,
|
||||
mi_option_max_warnings,
|
||||
mi_option_max_segment_reclaim,
|
||||
mi_option_destroy_on_exit,
|
||||
_mi_option_last
|
||||
} 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
|
||||
|
@ -598,7 +598,7 @@ static void mi_cdecl mi_process_done(void) {
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MI_SKIP_COLLECT_ON_EXIT
|
||||
#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
|
||||
@ -608,6 +608,11 @@ static void mi_cdecl mi_process_done(void) {
|
||||
#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)) {
|
||||
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
|
||||
{ 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors 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);
|
||||
|
@ -32,7 +32,7 @@ int main() {
|
||||
// invalid_free();
|
||||
// test_reserved();
|
||||
// negative_stat();
|
||||
test_heap_walk();
|
||||
// test_heap_walk();
|
||||
// alloc_huge();
|
||||
|
||||
void* p1 = malloc(78);
|
||||
|
Loading…
x
Reference in New Issue
Block a user