diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-10-24 14:30:51 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-10-24 14:30:51 +0200 |
| commit | 2e9bc93e1f1b989707941b8a1f43488d23f411c7 (patch) | |
| tree | 7bc51484b4aca8985901da2e64b61e0fc2be5910 /src/custommem.c | |
| parent | e2a993a4255e1d17a067727b959afce507c20eec (diff) | |
| download | box64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.tar.gz box64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.zip | |
[DYNAREC] Use customMalloc for internal dynarec stuff (fixed starbound)
Diffstat (limited to 'src/custommem.c')
| -rw-r--r-- | src/custommem.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/custommem.c b/src/custommem.c index 9a34d2f6..e8abdd86 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -75,6 +75,7 @@ typedef struct blocklist_s { void* block; size_t maxfree; size_t size; + void* first; } blocklist_t; #define MMAPSIZE (256*1024) // allocate 256kb sized blocks @@ -125,6 +126,23 @@ static void* getFirstBlock(void* block, size_t maxsize, size_t* size, void* star return NULL; } +static void* getNextFreeBlock(void* block) +{ + blockmark_t *m = (blockmark_t*)block; + while (m->next.fill) { + m = NEXT_BLOCK(m); + }; + return m; +} +static void* getPrevFreeBlock(void* block) +{ + blockmark_t *m = (blockmark_t*)block; + do { + m = PREV_BLOCK(m); + } while (m->next.fill); + return m; +} + static size_t getMaxFreeBlock(void* block, size_t block_size, void* start) { // get start of block @@ -271,11 +289,13 @@ void* customMalloc(size_t size) for(int i=0; i<n_blocks; ++i) { if(p_blocks[i].maxfree>=size) { size_t rsize = 0; - sub = getFirstBlock(p_blocks[i].block, size, &rsize, NULL); + sub = getFirstBlock(p_blocks[i].first, size, &rsize, NULL); if(sub) { void* ret = allocBlock(p_blocks[i].block, sub, size, NULL); + if(sub==p_blocks[i].first) + p_blocks[i].first = getNextFreeBlock(sub); if(rsize==p_blocks[i].maxfree) - p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL); + p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first); pthread_mutex_unlock(&mutex_blocks); return ret; } @@ -294,6 +314,7 @@ void* customMalloc(size_t size) void* p = box_calloc(1, allocsize); #endif p_blocks[i].block = p; + p_blocks[i].first = p; p_blocks[i].size = allocsize; // setup marks blockmark_t* m = (blockmark_t*)p; @@ -329,7 +350,9 @@ void* customRealloc(void* p, size_t size) && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) { void* sub = (void*)(addr-sizeof(blockmark_t)); if(expandBlock(p_blocks[i].block, sub, size)) { - p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL); + if(sub<p_blocks[i].first && p+size<p_blocks[i].first) + p_blocks[i].first = getNextFreeBlock(sub); + p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first); pthread_mutex_unlock(&mutex_blocks); return p; } @@ -355,7 +378,10 @@ void customFree(void* p) if ((addr>(uintptr_t)p_blocks[i].block) && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) { void* sub = (void*)(addr-sizeof(blockmark_t)); + void* n = NEXT_BLOCK((blockmark_t*)sub); size_t newfree = freeBlock(p_blocks[i].block, sub, NULL); + if(sub<=p_blocks[i].first) + p_blocks[i].first = getPrevFreeBlock(n); if(p_blocks[i].maxfree < newfree) p_blocks[i].maxfree = newfree; pthread_mutex_unlock(&mutex_blocks); return; @@ -1214,7 +1240,7 @@ void relockCustommemMutex(int locks) { #define GO(A, B) \ if(locks&(1<<B)) \ - pthread_mutex_lock(&A); \ + pthread_mutex_trylock(&A); \ GO(mutex_blocks, 0) GO(mutex_prot, 1) |