mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-10 17:29:31 +03:00
set delayed decommit mask more precisely to only decommit currently committed blocks
This commit is contained in:
parent
2cffc3b851
commit
e4ddc75069
2 changed files with 8 additions and 6 deletions
|
@ -264,7 +264,7 @@ typedef mi_page_t mi_slice_t;
|
|||
typedef int64_t mi_msecs_t;
|
||||
|
||||
|
||||
// Segments are large allocated memory blocks (2mb on 64 bit) from
|
||||
// Segments are large allocated memory blocks (8mb on 64 bit) from
|
||||
// the OS. Inside segments we allocated fixed size _pages_ that
|
||||
// contain blocks.
|
||||
typedef struct mi_segment_s {
|
||||
|
|
|
@ -137,6 +137,7 @@ static bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
|||
mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
|
||||
mi_assert_internal(segment->abandoned <= segment->used);
|
||||
mi_assert_internal(segment->thread_id == 0 || segment->thread_id == _mi_thread_id());
|
||||
mi_assert_internal((segment->commit_mask & segment->decommit_mask) == segment->decommit_mask); // can only decommit committed blocks
|
||||
//mi_assert_internal(segment->segment_info_size % MI_SEGMENT_SLICE_SIZE == 0);
|
||||
mi_slice_t* slice = &segment->slices[0];
|
||||
const mi_slice_t* end = mi_segment_slices_end(segment);
|
||||
|
@ -414,8 +415,9 @@ static void mi_segment_commitx(mi_segment_t* segment, bool commit, uint8_t* p, s
|
|||
if (commit && (segment->decommit_mask & mask) != 0) {
|
||||
segment->decommit_expire = _mi_clock_now() + mi_option_get(mi_option_reset_delay);
|
||||
}
|
||||
// always undo delayed decommits
|
||||
segment->decommit_mask &= ~mask;
|
||||
// always undo delayed decommits
|
||||
segment->decommit_mask &= ~mask;
|
||||
mi_assert_internal((segment->commit_mask & segment->decommit_mask) == segment->decommit_mask);
|
||||
}
|
||||
|
||||
static void mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
||||
|
@ -425,19 +427,19 @@ static void mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_
|
|||
|
||||
static void mi_segment_perhaps_decommit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
||||
if (!segment->allow_decommit) return;
|
||||
if (segment->commit_mask == 1) return; // fully decommitted
|
||||
if (segment->commit_mask == 1) return; // fully decommitted (1 = the initial segment metadata span)
|
||||
if (mi_option_get(mi_option_reset_delay) == 0) {
|
||||
mi_segment_commitx(segment, false, p, size, stats);
|
||||
}
|
||||
else {
|
||||
// create mask
|
||||
// register for future decommit in the decommit mask
|
||||
uint8_t* start;
|
||||
size_t full_size;
|
||||
uintptr_t mask = mi_segment_commit_mask(segment, true /*conservative*/, p, size, &start, &full_size);
|
||||
if (mask==0 || full_size==0) return;
|
||||
|
||||
// update delayed commit
|
||||
segment->decommit_mask |= mask;
|
||||
segment->decommit_mask |= (mask & segment->commit_mask); // only decommit what is committed; span_free may try to decommit more
|
||||
segment->decommit_expire = _mi_clock_now() + mi_option_get(mi_option_reset_delay);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue