Core: Fixed issue with allocator 4KB reserve

git-svn-id: svn://ultimatepp.org/upp/trunk@13633 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2019-10-08 09:03:02 +00:00
parent 9844b9f50c
commit b00a33ce5a
3 changed files with 24 additions and 19 deletions

View file

@ -283,7 +283,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
int HugeFree(void *ptr);
bool HugeTryRealloc(void *ptr, size_t count);
static int Ksz(int k) {
static int Ksz(int k) { // small block size classes
static int sz[] = {
// 0 1 2 3 4 5 6 7 8 9 10 11
32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384,
@ -384,7 +384,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
static Heap aux; // Single global auxiliary heap to store orphans and global list of free pages
static size_t huge_4KB_count; // total number of 4KB pages in small/large/huge blocks
static int free_4KB; // empty 4KB pages
static int free_4KB; // number of empty 4KB pages (linked in aux.empty)
static size_t big_size; // blocks >~64KB
static size_t big_count;
static size_t sys_size; // blocks allocated directly from system (included in big too)
@ -424,6 +424,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
void *Allok(int k);
void Free(void *ptr, Page *page, int k);
void Free(void *ptr, int k);
void Free4KB(int k, Page *page);
static bool FreeSmallEmpty(int size4KB, int count = INT_MAX);

View file

@ -144,10 +144,7 @@ void Heap::Shutdown()
if(empty[i]) {
ASSERT(empty[i]->freelist);
ASSERT(empty[i]->active == 0);
empty[i]->heap = &aux;
empty[i]->next = aux.empty[i];
aux.empty[i] = empty[i];
free_4KB++;
Free4KB(i, empty[i]);
LLOG("Orphan empty " << (void *)empty[i]);
}
}

View file

@ -184,28 +184,35 @@ void Heap::FreeK(void *ptr, Page *page, int k)
page->Unlink();
if(this == &aux) {
LLOG("...is aux " << asString(free_4KB));
page->next = empty[k];
empty[k] = page;
free_4KB++;
Mutex::Lock __(mutex);
Free4KB(k, page);
}
else {
if(empty[k]) { // Keep one hot empty page per klass in thread, put rest to 'aux' global storage
LLOG("Global free " << k << " " << (void *)empty[k]);
Mutex::Lock __(mutex);
if(free_4KB < max_free_spages) { // only keep max_free_spages, release if more
empty[k]->heap = &aux;
empty[k]->next = aux.empty[k];
aux.empty[k] = empty[k];
free_4KB++;
}
else
aux.HugeFree(empty[k]);
Free4KB(k, empty[k]); // Free current hot page to reserve/huge
}
empty[k] = page;
empty[k] = page; // this empty page is now hot
}
}
}
void Heap::Free4KB(int k, Page *page)
{ // put empty 4KB to aux reserve or back to huge blocks if the reserve is full
LLOG("Global Free4KB " << k << " " << (void *)empty);
if(free_4KB < max_free_spages) { // only keep max_free_spages, release if more
page->heap = &aux;
page->next = aux.empty[k];
aux.empty[k] = page;
free_4KB++;
LLOG("Reserve 4KB " << asString(free_4KB));
}
else {
aux.HugeFree(page);
LLOG("HugeFree 4KB " << asString(free_4KB));
}
}
force_inline
void Heap::Free(void *ptr, Page *page, int k)
{