about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-06-24 17:08:28 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-06-24 17:08:28 +0200
commit4219af78f45fd1a2ba54e0ea2019a70de2b73684 (patch)
tree2c10b8daa6f06ce608d87a35f69fe7f42c3a4ea7 /src
parent0352f2e6f0be908a891ed550efedbd724e50ceba (diff)
downloadbox64-4219af78f45fd1a2ba54e0ea2019a70de2b73684.tar.gz
box64-4219af78f45fd1a2ba54e0ea2019a70de2b73684.zip
Try to improve custom memory allocator
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/src/custommem.c b/src/custommem.c
index dfeb6bbc..d2b752c0 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -187,6 +187,8 @@ static size_t getMaxFreeBlock(void* block, size_t block_size, void* start)
     }
 }
 
+#define THRESHOLD   (128-2*sizeof(blockmark_t))
+
 static void* allocBlock(void* block, void *sub, size_t size, void** pstart)
 {
     (void)block;
@@ -196,25 +198,26 @@ static void* allocBlock(void* block, void *sub, size_t size, void** pstart)
 
     s->next.fill = 1;
     // check if a new mark is worth it
-    if(s->next.size>size+2*sizeof(blockmark_t))
+    if(s->next.size>size+2*sizeof(blockmark_t)+THRESHOLD) {
+        size_t old_size = s->next.size;
         s->next.size = size;
-    blockmark_t *m = NEXT_BLOCK(s);   // this is new n
-    m->prev.fill = 1;
-    if(n!=m) {
-        // new mark
+        blockmark_t *m = NEXT_BLOCK(s);
+        m->prev.fill = 1;
         m->prev.size = s->next.size;
         m->next.fill = 0;
-        m->next.size = ((uintptr_t)n - (uintptr_t)m) - sizeof(blockmark_t);
+        m->next.size = old_size - (size + sizeof(blockmark_t));
         n->prev.fill = 0;
         n->prev.size = m->next.size;
+        n = m;
+    } else {
+        n->prev.fill = 1;
     }
 
     if(pstart && sub==*pstart) {
         // get the next free block
-        m = (blockmark_t*)*pstart;
-        while(m->next.fill)
-            m = NEXT_BLOCK(m);
-        *pstart = (void*)m;
+        while(n->next.fill)
+            n = NEXT_BLOCK(n);
+        *pstart = (void*)n;
     }
     return (void*)((uintptr_t)sub + sizeof(blockmark_t));
 }
@@ -228,7 +231,7 @@ static size_t freeBlock(void *block, void* sub, void** pstart)
     s->next.fill = 0;
     n->prev.fill = 0;
     // check if merge with previous
-    if (s->prev.x32 && !s->prev.fill) {
+    if (m!=s && s->prev.x32 && !s->prev.fill) {
         // remove s...
         m->next.size += s->next.size + sizeof(blockmark_t);
         n->prev.size = m->next.size;
@@ -264,7 +267,7 @@ static int expandBlock(void* block, void* sub, size_t newsize)
     if((size_t)(s->next.size + n->next.size + sizeof(blockmark_t)) < newsize)
         return 0;   // free space too short
     // ok, doing the alloc!
-    if((s->next.size+n->next.size+sizeof(blockmark_t))-newsize<2*sizeof(blockmark_t))
+    if((s->next.size+n->next.size+sizeof(blockmark_t))-newsize<THRESHOLD+2*sizeof(blockmark_t))
         s->next.size += n->next.size+sizeof(blockmark_t);
     else
         s->next.size = newsize+sizeof(blockmark_t);
@@ -303,10 +306,10 @@ int printBlockCoherent(int i)
     if(p_blocks[i].first && p_blocks[i].first!=first) {printf_log(LOG_NONE, "First %p and stored first %p differs for block %d\n", first, p_blocks[i].first, i); ret = 0;}
     // check if maxfree is correct, with no hint
     size_t maxfree = getMaxFreeBlock(m, p_blocks[i].size, NULL);
-    if(maxfree != p_blocks[i].maxfree) {printf_log(LOG_NONE, "Maxfree without hint %zd and stored maxfree %zd differs for block %d\n", maxfree, p_blocks[i].maxfree); ret = 0;}
+    if(maxfree != p_blocks[i].maxfree) {printf_log(LOG_NONE, "Maxfree without hint %zd and stored maxfree %zd differs for block %d\n", maxfree, p_blocks[i].maxfree, i); ret = 0;}
     // check if maxfree from first is correct
     maxfree = getMaxFreeBlock(m, p_blocks[i].size, p_blocks[i].first);
-    if(maxfree != p_blocks[i].maxfree) {printf_log(LOG_NONE, "Maxfree with hint %zd and stored maxfree %zd differs for block %d\n", maxfree, p_blocks[i].maxfree); ret = 0;}
+    if(maxfree != p_blocks[i].maxfree) {printf_log(LOG_NONE, "Maxfree with hint %zd and stored maxfree %zd differs for block %d\n", maxfree, p_blocks[i].maxfree, i); ret = 0;}
     // check chain
     blockmark_t* last = (blockmark_t*)(((uintptr_t)m)+p_blocks[i].size-sizeof(blockmark_t));
     while(m<last) {
@@ -345,8 +348,6 @@ void testAllBlocks()
     printf_log(LOG_NONE, "Total %d blocks, for %zd allocated memory, max_free %zd, toatal fragmented free %zd\n", n_blocks, total, max_free, fragmented_free);
 }
 
-#define THRESHOLD   (128-2*sizeof(blockmark_t))
-
 static size_t roundSize(size_t size)
 {
     if(!size)