about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-09-04 15:23:37 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-09-04 15:23:37 +0200
commitb5e405b2b447c64b9dcbcaf5fc5e0cf31de66d5e (patch)
tree5026fb0d9668347f10b14781cb8587e7a2006731
parent354f46f41bfe08be1e9f144389d3333cfc49f2f4 (diff)
downloadbox64-b5e405b2b447c64b9dcbcaf5fc5e0cf31de66d5e.tar.gz
box64-b5e405b2b447c64b9dcbcaf5fc5e0cf31de66d5e.zip
Added an rbtree is Custom Mem Manager to speedup customFree and customRealloc
-rw-r--r--src/custommem.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 292d1b87..f227bbee 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -66,6 +66,7 @@ static int inited = 0;
 
 rbtree*  mapallmem = NULL;
 static rbtree*  mmapmem = NULL;
+static rbtree*  blockstree = NULL;
 
 typedef struct blocklist_s {
     void*               block;
@@ -359,7 +360,7 @@ void testAllBlocks()
     size_t max_free = 0;
     for(int i=0; i<n_blocks; ++i) {
         if(!printBlockCoherent(i))
-            printBlock(p_blocks[i].block, p_blocks[i].block);
+            printBlock(p_blocks[i].block, p_blocks[i].first);
         total += p_blocks[i].size;
         if(max_free<p_blocks[i].maxfree)
             max_free = p_blocks[i].maxfree;
@@ -385,6 +386,21 @@ static size_t roundSize(size_t size)
     return size;
 }
 
+blocklist_t* findBlock(uintptr_t addr)
+{
+    if(blockstree) {
+        uint32_t i;
+        uintptr_t end;
+        if(rb_get_end(blockstree, addr, &i, &end))
+            return &p_blocks[i];
+    } else {
+        for(int i=0; i<n_blocks; ++i)
+            if((addr>=(uintptr_t)p_blocks[i].block) && (addr<=(uintptr_t)p_blocks[i].block+p_blocks[i].size))
+                return &p_blocks[i];
+    }
+    return NULL;
+}
+
 #ifdef DYNAREC
 #define GET_PROT_WAIT(A, B) \
         uint32_t A;         \
@@ -491,6 +507,8 @@ void* internal_customMalloc(size_t size, int is32bits)
     void* ret  = allocBlock(p_blocks[i].block, p, size, &p_blocks[i].first);
     p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first);
     mutex_unlock(&mutex_blocks);
+    if(blockstree)
+        rb_set(blockstree, (uintptr_t)p, (uintptr_t)p+allocsize, i);
     if(mapallmem) {
         // defer the setProtection...
         //setProtection((uintptr_t)p, allocsize, PROT_READ | PROT_WRITE);
@@ -533,19 +551,23 @@ void* internal_customRealloc(void* p, size_t size, int is32bits)
     uintptr_t addr = (uintptr_t)p;
     mutex_lock(&mutex_blocks);
     for(int i=0; i<n_blocks; ++i) {
-        if (p_blocks[i].block && (addr>(uintptr_t)p_blocks[i].block) 
-         && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
+        blocklist_t* l = findBlock(addr);
+        if(l) {
             blockmark_t* sub = (blockmark_t*)(addr-sizeof(blockmark_t));
-            if(expandBlock(p_blocks[i].block, sub, size, &p_blocks[i].first)) {
-                p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first);
+            if(expandBlock(l->block, sub, size, &l->first)) {
+                l->maxfree = getMaxFreeBlock(l->block, l->size, l->first);
                 mutex_unlock(&mutex_blocks);
                 return p;
             }
             mutex_unlock(&mutex_blocks);
             void* newp = internal_customMalloc(size, is32bits);
             memcpy(newp, p, sizeBlock(sub));
-            size_t newfree = freeBlock(p_blocks[i].block, p_blocks[i].size, sub, &p_blocks[i].first);
-            if(p_blocks[i].maxfree < newfree) p_blocks[i].maxfree = newfree;
+            // disabling the "fast free", as mutex has been released, so things are not garantied to stay as-is
+            internal_customFree(p, is32bits);
+            //mutex_lock(&mutex_blocks);
+            //size_t newfree = freeBlock(l->block, l->size, sub, &l->first);
+            //if(l->maxfree < newfree) l->maxfree = newfree;
+            //mutex_unlock(&mutex_blocks);
             return newp;
         }
     }
@@ -573,11 +595,11 @@ void internal_customFree(void* p, int is32bits)
     uintptr_t addr = (uintptr_t)p;
     mutex_lock(&mutex_blocks);
     for(int i=0; i<n_blocks; ++i) {
-        if (p_blocks[i].block && (addr>(uintptr_t)p_blocks[i].block) 
-         && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
+        blocklist_t* l = findBlock(addr);
+        if(l) {
             blockmark_t* sub = (blockmark_t*)(addr-sizeof(blockmark_t));
-            size_t newfree = freeBlock(p_blocks[i].block, p_blocks[i].size, sub, &p_blocks[i].first);
-            if(p_blocks[i].maxfree < newfree) p_blocks[i].maxfree = newfree;
+            size_t newfree = freeBlock(l->block, l->size, sub, &l->first);
+            if(l->maxfree < newfree) l->maxfree = newfree;
             mutex_unlock(&mutex_blocks);
             return;
         }
@@ -705,6 +727,8 @@ void* internal_customMemAligned(size_t align, size_t size, int is32bits)
     mutex_unlock(&mutex_blocks);
     if(mapallmem)
         setProtection((uintptr_t)p, allocsize, PROT_READ | PROT_WRITE);
+    if(blockstree)
+        rb_set(blockstree, (uintptr_t)p, (uintptr_t)p+allocsize, i);
     return ret;
 }
 void* customMemAligned(size_t align, size_t size)
@@ -1858,6 +1882,11 @@ void init_custommem_helper(box64context_t* ctx)
     if(inited) // already initialized
         return;
     inited = 1;
+    blockstree = init_rbtree();
+    // if there is some blocks already
+    if(n_blocks)
+        for(int i=0; i<n_blocks; ++i)
+            rb_set(blockstree, (uintptr_t)p_blocks[i].block, (uintptr_t)p_blocks[i].block+p_blocks[i].size, i);
     memprot = init_rbtree();
     sigfillset(&critical_prot);
     init_mutexes();
@@ -1978,6 +2007,8 @@ void fini_custommem_helper(box64context_t *ctx)
     mmapmem = NULL;
     delete_rbtree(mapallmem);
     mapallmem = NULL;
+    delete_rbtree(blockstree);
+    blockstree = NULL;
 
     for(int i=0; i<n_blocks; ++i)
         internal_munmap(p_blocks[i].block, p_blocks[i].size);