remove delayed reset option (for now)

This commit is contained in:
Daan Leijen 2019-11-20 14:13:02 -08:00
parent 56b9fac4bf
commit 30e2c54adb
4 changed files with 142 additions and 240 deletions

View file

@ -53,9 +53,6 @@ void _mi_arena_free(void* p, size_t size, size_t memid, mi_stats_t* stats);
void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld);
// local
static bool mi_delay_remove(mi_delay_slots_t* delay_slots, void* p, size_t size);
// Constants
#if (MI_INTPTR_SIZE==8)
@ -354,8 +351,6 @@ void _mi_mem_free(void* p, size_t size, size_t id, mi_os_tld_t* tld) {
if (p==NULL) return;
if (size==0) return;
mi_delay_remove(tld->reset_delay, p, size);
size_t arena_memid = 0;
mi_bitmap_index_t bit_idx;
mem_region_t* region;
@ -424,7 +419,6 @@ void _mi_mem_collect(mi_os_tld_t* tld) {
bool is_eager_committed;
void* start = mi_region_info_read(mi_atomic_read(&regions[i].info), NULL, &is_eager_committed);
if (start != NULL) { // && !_mi_os_is_huge_reserved(start)) {
mi_delay_remove(tld->reset_delay, start, MI_REGION_SIZE);
_mi_arena_free(start, MI_REGION_SIZE, region->arena_memid, tld->stats);
}
// and release
@ -434,142 +428,23 @@ void _mi_mem_collect(mi_os_tld_t* tld) {
}
}
/* ----------------------------------------------------------------------------
Delay slots
-----------------------------------------------------------------------------*/
typedef void (mi_delay_resolve_fun)(void* addr, size_t size, void* arg);
static void mi_delay_insert(mi_delay_slots_t* ds,
mi_msecs_t delay, uint8_t* addr, size_t size,
mi_delay_resolve_fun* resolve, void* arg)
{
if (ds == NULL || delay==0 || addr==NULL || size==0) {
resolve(addr, size, arg);
return;
}
mi_msecs_t now = _mi_clock_now();
mi_delay_slot_t* oldest = &ds->slots[0];
// walk through all slots, resolving expired ones.
// remember the oldest slot to insert the new entry in.
size_t newcount = 0;
for (size_t i = 0; i < ds->count; i++) {
mi_delay_slot_t* slot = &ds->slots[i];
if (slot->expire == 0) {
// empty slot
oldest = slot;
}
// TODO: should we handle overlapping areas too?
else if (slot->addr <= addr && slot->addr + slot->size >= addr + size) {
// earlier slot encompasses new area, increase expiration
slot->expire = now + delay;
delay = 0;
}
else if (addr <= slot->addr && addr + size >= slot->addr + slot->size) {
// new one encompasses old slot, overwrite
slot->expire = now + delay;
slot->addr = addr;
slot->size = size;
delay = 0;
}
else if (slot->expire < now) {
// expired slot, resolve now
slot->expire = 0;
resolve(slot->addr, slot->size, arg);
}
else if (oldest->expire > slot->expire) {
oldest = slot;
newcount = i+1;
}
else {
newcount = i+1;
}
}
ds->count = newcount;
if (delay>0) {
// not yet registered, use the oldest slot (or a new one if there is space)
if (ds->count < ds->capacity) {
oldest = &ds->slots[ds->count];
ds->count++;
}
else if (oldest->expire > 0) {
resolve(oldest->addr, oldest->size, arg); // evict if not empty
}
mi_assert_internal((oldest - ds->slots) < (ptrdiff_t)ds->count);
oldest->expire = now + delay;
oldest->addr = addr;
oldest->size = size;
}
}
static bool mi_delay_remove(mi_delay_slots_t* ds, void* p, size_t size)
{
if (ds == NULL || p==NULL || size==0) return false;
uint8_t* addr = (uint8_t*)p;
bool done = false;
size_t newcount = 0;
// walk through all valid slots
for (size_t i = 0; i < ds->count; i++) {
mi_delay_slot_t* slot = &ds->slots[i];
if (slot->addr <= addr && slot->addr + slot->size >= addr + size) {
// earlier slot encompasses the area; remove it
slot->expire = 0;
done = true;
}
else if (addr <= slot->addr && addr + size >= slot->addr + slot->size) {
// new one encompasses old slot, remove it
slot->expire = 0;
}
else if ((addr <= slot->addr && addr + size > slot->addr) ||
(addr < slot->addr + slot->size && addr + size >= slot->addr + slot->size)) {
// partial overlap
// can happen with a large object spanning onto some partial end block
// mi_assert_internal(false);
slot->expire = 0;
}
else {
newcount = i + 1;
}
}
ds->count = newcount;
return done;
}
static void mi_resolve_reset(void* p, size_t size, void* vtld) {
mi_os_tld_t* tld = (mi_os_tld_t*)vtld;
_mi_os_reset(p, size, tld->stats);
}
bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld) {
mi_delay_insert(tld->reset_delay, mi_option_get(mi_option_reset_delay),
(uint8_t*)p, size, &mi_resolve_reset, tld);
return true;
}
bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) {
if (!mi_delay_remove(tld->reset_delay, (uint8_t*)p, size)) {
return _mi_os_unreset(p, size, is_zero, tld->stats);
}
return true;
}
/* ----------------------------------------------------------------------------
Other
-----------------------------------------------------------------------------*/
bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld) {
return _mi_os_reset(p, size, tld->stats);
}
bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) {
return _mi_os_unreset(p, size, is_zero, tld->stats);
}
bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) {
mi_delay_remove(tld->reset_delay,p, size);
return _mi_os_commit(p, size, is_zero, tld->stats);
}
bool _mi_mem_decommit(void* p, size_t size, mi_os_tld_t* tld) {
mi_delay_remove(tld->reset_delay, p, size);
return _mi_os_decommit(p, size, tld->stats);
}