mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-04 22:49:32 +03:00
add option to reset eagerly when a segment is abandoned
This commit is contained in:
parent
b8072aaacb
commit
8d8f355ed0
3 changed files with 14 additions and 7 deletions
|
@ -273,6 +273,7 @@ typedef enum mi_option_e {
|
|||
mi_option_reserve_huge_os_pages,
|
||||
mi_option_segment_cache,
|
||||
mi_option_page_reset,
|
||||
mi_option_abandoned_page_reset,
|
||||
mi_option_segment_reset,
|
||||
mi_option_eager_commit_delay,
|
||||
mi_option_reset_delay,
|
||||
|
|
|
@ -68,6 +68,7 @@ static mi_option_desc_t options[_mi_option_last] =
|
|||
{ 0, UNINIT, MI_OPTION(reserve_huge_os_pages) },
|
||||
{ 0, UNINIT, MI_OPTION(segment_cache) }, // cache N segments per thread
|
||||
{ 0, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free
|
||||
{ 0, UNINIT, MI_OPTION(abandoned_page_reset) },// reset free page memory when a thread terminates
|
||||
{ 0, UNINIT, MI_OPTION(segment_reset) }, // reset segment memory on free (needs eager commit)
|
||||
{ 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed
|
||||
{ 100, UNINIT, MI_OPTION(reset_delay) }, // reset delay in milli-seconds
|
||||
|
|
|
@ -326,12 +326,15 @@ static void mi_pages_reset_remove(mi_page_t* page, mi_segments_tld_t* tld) {
|
|||
page->used = 0;
|
||||
}
|
||||
|
||||
static void mi_pages_reset_remove_all_in_segment(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||
if (segment->mem_is_fixed) return;
|
||||
static void mi_pages_reset_remove_all_in_segment(mi_segment_t* segment, bool force_reset, mi_segments_tld_t* tld) {
|
||||
if (segment->mem_is_fixed) return; // never reset in huge OS pages
|
||||
for (size_t i = 0; i < segment->capacity; i++) {
|
||||
mi_page_t* page = &segment->pages[i];
|
||||
if (!page->segment_in_use && !page->is_reset) {
|
||||
mi_pages_reset_remove(page, tld);
|
||||
if (force_reset) {
|
||||
mi_page_reset(segment, page, 0, tld);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mi_assert_internal(mi_page_not_in_queue(page,tld));
|
||||
|
@ -670,7 +673,9 @@ static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind,
|
|||
static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) {
|
||||
UNUSED(force);
|
||||
mi_assert(segment != NULL);
|
||||
mi_pages_reset_remove_all_in_segment(segment, tld);
|
||||
// note: don't reset pages even on abandon as the whole segment is freed? (and ready for reuse)
|
||||
bool force_reset = (force && mi_option_is_enabled(mi_option_abandoned_page_reset));
|
||||
mi_pages_reset_remove_all_in_segment(segment, force_reset, tld);
|
||||
mi_segment_remove_from_free_queue(segment,tld);
|
||||
|
||||
mi_assert_expensive(!mi_segment_queue_contains(&tld->small_free, segment));
|
||||
|
@ -841,7 +846,7 @@ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
|||
|
||||
// remove the segment from the free page queue if needed
|
||||
mi_reset_delayed(tld);
|
||||
mi_pages_reset_remove_all_in_segment(segment, tld); // do not force reset on free pages in an abandoned segment, as it is already done in segment_thread_collect
|
||||
mi_pages_reset_remove_all_in_segment(segment, mi_option_is_enabled(mi_option_abandoned_page_reset), tld);
|
||||
mi_segment_remove_from_free_queue(segment, tld);
|
||||
mi_assert_internal(segment->next == NULL && segment->prev == NULL);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue