enable non eager commit

This commit is contained in:
daan 2019-07-10 07:24:56 -07:00
commit 224951695a
5 changed files with 46 additions and 28 deletions

View file

@ -202,16 +202,11 @@ static void mi_segment_os_free(mi_segment_t* segment, size_t segment_size, mi_se
#define MI_SEGMENT_CACHE_MAX (4)
#define MI_SEGMENT_CACHE_FRACTION (8)
// note: returned segment may be partially reset
static mi_segment_t* mi_segment_cache_pop(size_t segment_size, mi_segments_tld_t* tld) {
if (segment_size != 0 && segment_size != MI_SEGMENT_SIZE) return NULL;
mi_segment_t* segment = tld->cache;
if (segment == NULL) return NULL;
if (mi_option_is_enabled(mi_option_eager_commit) &&
(mi_option_is_enabled(mi_option_cache_reset) || mi_option_is_enabled(mi_option_page_reset)))
{
// ensure the memory is available
_mi_mem_unreset((uint8_t*)segment + segment->segment_info_size, segment->segment_size - segment->segment_info_size, tld->stats);
}
tld->cache_count--;
tld->cache = segment->next;
segment->next = NULL;
@ -298,9 +293,16 @@ static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind,
protection_still_good = true; // otherwise, the guard pages are still in place
}
}
if (page_kind != MI_PAGE_SMALL && !mi_option_is_enabled(mi_option_eager_commit) &&
(mi_option_is_enabled(mi_option_cache_reset) || mi_option_is_enabled(mi_option_page_reset))) {
_mi_mem_commit(segment, segment->segment_size, tld->stats);
if (!mi_option_is_enabled(mi_option_eager_commit)) {
if (page_kind != MI_PAGE_SMALL) {
_mi_mem_commit(segment, segment->segment_size, tld->stats);
}
else {
// ok, commit (and unreset) on demand again
}
}
else if (mi_option_is_enabled(mi_option_cache_reset) || mi_option_is_enabled(mi_option_page_reset)) {
_mi_mem_unreset(segment, segment->segment_size, tld->stats);
}
}
else {
@ -349,7 +351,8 @@ static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind,
segment->cookie = _mi_ptr_cookie(segment);
for (uint8_t i = 0; i < segment->capacity; i++) {
segment->pages[i].segment_idx = i;
segment->pages[i].is_reset = !commit;
segment->pages[i].is_reset = false;
segment->pages[i].is_committed = commit;
}
_mi_stat_increase(&tld->stats->page_committed, segment->segment_info_size);
//fprintf(stderr,"mimalloc: alloc segment at %p\n", (void*)segment);
@ -421,18 +424,18 @@ static mi_page_t* mi_segment_find_free(mi_segment_t* segment, mi_stats_t* stats)
for (size_t i = 0; i < segment->capacity; i++) {
mi_page_t* page = &segment->pages[i];
if (!page->segment_in_use) {
if (page->is_reset) {
if (page->is_reset || !page->is_committed) {
size_t psize;
uint8_t* start = _mi_page_start(segment, page, &psize);
page->is_reset = false;
if (mi_option_is_enabled(mi_option_eager_commit)) {
_mi_mem_unreset(start, psize, stats);
}
else {
// note we could allow both lazy commit, and page level reset if we add a `is_commit` flag...
// for now we use commit for both
_mi_mem_commit(start, psize, stats);
mi_assert_internal(!(page->is_reset && !page->is_committed));
if (!page->is_committed) {
page->is_committed = true;
_mi_mem_commit(start,psize,stats);
}
if (page->is_reset) {
page->is_reset = false;
_mi_mem_unreset(start, psize, stats);
}
}
return page;
}
@ -452,6 +455,7 @@ static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, mi_sta
UNUSED(stats);
mi_assert_internal(page->segment_in_use);
mi_assert_internal(mi_page_all_free(page));
mi_assert_internal(page->is_committed);
size_t inuse = page->capacity * page->block_size;
_mi_stat_decrease(&stats->page_committed, inuse);
_mi_stat_decrease(&stats->pages, 1);
@ -467,10 +471,12 @@ static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, mi_sta
// zero the page data
uint8_t idx = page->segment_idx; // don't clear the index
bool is_reset = page->is_reset; // don't clear the reset flag
bool is_committed = page->is_committed; // don't clear the commit flag
memset(page, 0, sizeof(*page));
page->segment_idx = idx;
page->segment_in_use = false;
page->is_reset = is_reset;
page->is_committed = is_committed;
segment->used--;
}