From e7a860fa2af20fd36902ebd47f027e31f91e9519 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 25 Jun 2019 17:11:11 +0000 Subject: [PATCH] Core: Heap options git-svn-id: svn://ultimatepp.org/upp/trunk@13439 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Heap.h | 1 + uppsrc/Core/HeapImp.h | 2 ++ uppsrc/Core/hheap.cpp | 4 +++- uppsrc/Core/sheap.cpp | 15 ++++++++------- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/uppsrc/Core/Heap.h b/uppsrc/Core/Heap.h index 30bb0fd4e..98ab8c898 100644 --- a/uppsrc/Core/Heap.h +++ b/uppsrc/Core/Heap.h @@ -2,6 +2,7 @@ struct MemoryOptions { // sizes are in KB int master_block = 16384; // master block size int sys_block_limit = 16384; // > that this: allocate directly from the system int master_reserve = 1; // free master blocks kept in reserve + int small_reserve = 256; // free formatted small block pages kept in reserve }; #ifdef UPP_HEAP diff --git a/uppsrc/Core/HeapImp.h b/uppsrc/Core/HeapImp.h index caa344133..84e6b48b9 100644 --- a/uppsrc/Core/HeapImp.h +++ b/uppsrc/Core/HeapImp.h @@ -273,8 +273,10 @@ struct Heap : BlkHeap { REMOTE_OUT_SZ = 2000, // maximum size of remote frees to be buffered to flush at once }; + // allocator options: static word HPAGE; // size of master page, in 4KB units static int max_free_hpages; // maximum free master pages kept in reserve (if more, they are returned to the system) + static int max_free_spages; // maximum free small pages kept in reserve (but HugeAlloc also converts them) static word sys_block_limit; // > this (in 4KB) blocks are managed directly by system void *HugeAlloc(size_t count); // count in 4KB, client needs to not touch HugePrefix diff --git a/uppsrc/Core/hheap.cpp b/uppsrc/Core/hheap.cpp index 2e6cc8668..8e5ad03fb 100644 --- a/uppsrc/Core/hheap.cpp +++ b/uppsrc/Core/hheap.cpp @@ -16,13 +16,15 @@ namespace Upp { word Heap::HPAGE = 16 * 256; // 16MB default value word Heap::sys_block_limit = 16 * 256; // 16MB default value -int Heap::max_free_hpages = 4; // default value +int Heap::max_free_hpages = 1; // default value +int Heap::max_free_spages = 256; // default value (1MB) void MemorySetOptions(const MemoryOptions& opt) { Heap::HPAGE = (word)clamp(opt.master_block / 4, 256, 65535); Heap::sys_block_limit = (word)clamp((int)opt.sys_block_limit / 4, 16, (int)Heap::HPAGE); Heap::max_free_hpages = opt.master_reserve; + Heap::max_free_spages = opt.small_reserve; } BlkHeader_<4096> HugeHeapDetail::freelist[20][1]; // only single global Huge heap... diff --git a/uppsrc/Core/sheap.cpp b/uppsrc/Core/sheap.cpp index d59d3c9a5..5fe65fc73 100644 --- a/uppsrc/Core/sheap.cpp +++ b/uppsrc/Core/sheap.cpp @@ -185,14 +185,16 @@ void Heap::FreeK(void *ptr, Page *page, int k) 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); - empty[k]->heap = &aux; - empty[k]->next = aux.empty[k]; - aux.empty[k] = empty[k]; - free_4KB++; + if(free_4KB < max_free_spages) { + empty[k]->heap = &aux; + empty[k]->next = aux.empty[k]; + aux.empty[k] = empty[k]; + free_4KB++; + } + else + aux.HugeFree(empty[k]); } empty[k] = page; - if(16 * free_4KB > huge_4KB_count) // keep number of free 4KB blocks in check - FreeSmallEmpty(INT_MAX, int(free_4KB - huge_4KB_count / 32)); } } } @@ -242,7 +244,6 @@ size_t Heap::GetBlockSize(void *ptr) return LGetBlockSize(ptr); } - void Heap::SmallFreeDirect(void *ptr) { // does not need to check for target heap or small vs large LLOG("Free Direct " << ptr);