From ee3f2059dc7ca90b69d36354be2278f1668482d2 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 9 Jul 2019 20:22:53 -0700 Subject: [PATCH 1/2] fix leak in segment cache freeing --- src/init.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/init.c b/src/init.c index 0ac7388d..95559378 100644 --- a/src/init.c +++ b/src/init.c @@ -230,13 +230,16 @@ static bool _mi_heap_done(void) { heap = heap->tld->heap_backing; if (!mi_heap_is_initialized(heap)) return false; + // collect if not the main thread + if (heap != &_mi_heap_main) { + _mi_heap_collect_abandon(heap); + } + + // merge stats _mi_stats_done(&heap->tld->stats); - // free if not the main thread (or in debug mode) + // free if not the main thread if (heap != &_mi_heap_main) { - if (heap->page_count > 0) { - _mi_heap_collect_abandon(heap); - } _mi_os_free(heap, sizeof(mi_thread_data_t), &_mi_stats_main); } #if (MI_DEBUG > 0) @@ -322,7 +325,7 @@ void mi_thread_init(void) mi_attr_noexcept // don't further initialize for the main thread if (_mi_is_main_thread()) return; - mi_stat_increase(mi_get_default_heap()->tld->stats.threads, 1); + _mi_stat_increase(&mi_get_default_heap()->tld->stats.threads, 1); // set hooks so our mi_thread_done() will be called #if defined(_WIN32) && defined(MI_SHARED_LIB) @@ -342,7 +345,7 @@ void mi_thread_done(void) mi_attr_noexcept { // stats mi_heap_t* heap = mi_get_default_heap(); if (!_mi_is_main_thread() && mi_heap_is_initialized(heap)) { - mi_stat_decrease(heap->tld->stats.threads, 1); + _mi_stat_decrease(&heap->tld->stats.threads, 1); } // abandon the thread local heap From ad9db3a63343e5c216e4fc26f42a65f1a8cd14f9 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 9 Jul 2019 20:35:07 -0700 Subject: [PATCH 2/2] fix leak of huge segments in caches --- src/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/segment.c b/src/segment.c index 14f893e8..5d138f62 100644 --- a/src/segment.c +++ b/src/segment.c @@ -297,7 +297,7 @@ static bool mi_segment_cache_insert(mi_segment_t* segment, mi_segments_tld_t* tl void _mi_segment_thread_collect(mi_segments_tld_t* tld) { mi_segment_t* segment; while ((segment = mi_segment_cache_find(tld,0)) != NULL) { - mi_segment_os_free(segment, MI_SEGMENT_SIZE, tld); + mi_segment_os_free(segment, segment->segment_size, tld); } mi_assert_internal(tld->cache_count == 0 && tld->cache_size == 0); mi_assert_internal(mi_segment_queue_is_empty(&tld->cache));