X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fheap.c;h=bdf64de35fdc635674f8b91f55409dd401e17d3c;hb=0eb50bc9e604f654bdb0409bb66da03b733f906c;hp=7ce6bca872ce0123cfccefa239c10ab2bc4b1e94;hpb=8a8a744341df513d00d2e60adf5e88636856e65b;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/heap.c b/Usermode/Libraries/libc.so_src/heap.c index 7ce6bca8..bdf64de3 100644 --- a/Usermode/Libraries/libc.so_src/heap.c +++ b/Usermode/Libraries/libc.so_src/heap.c @@ -7,6 +7,12 @@ heap.c - Heap Manager #include #include "lib.h" +#if 0 +# define DEBUGS(s...) _SysDebug(s) +#else +# define DEBUGS(s...) do{}while(0) +#endif + // === Constants === #define MAGIC 0xACE55051 //AcessOS1 #define MAGIC_FREE (~MAGIC) @@ -19,6 +25,7 @@ typedef unsigned int Uint; typedef struct { uint32_t magic; size_t size; + char data[]; } heap_head; typedef struct { heap_head *header; @@ -38,6 +45,7 @@ EXPORT void *sbrk(int increment); LOCAL void *extendHeap(int bytes); static void *FindHeapBase(); LOCAL uint brk(uintptr_t newpos); +LOCAL void Heap_Dump(void); //Code @@ -53,7 +61,8 @@ EXPORT void *malloc(size_t bytes) size_t closestMatch = 0; void *bestMatchAddr = 0; heap_head *curBlock; - + +// _SysDebug("&_heap_start = %p, _heap_start = %p", &_heap_start, _heap_start); // Initialise Heap if(_heap_start == NULL) { @@ -63,6 +72,7 @@ EXPORT void *malloc(size_t bytes) } curBlock = _heap_start; +// _SysDebug("_heap_start = %p", _heap_start); bestSize = bytes + sizeof(heap_head) + sizeof(heap_foot) + BLOCK_SIZE - 1; bestSize = (bestSize/BLOCK_SIZE)*BLOCK_SIZE; //Round up to block size @@ -82,6 +92,7 @@ EXPORT void *malloc(size_t bytes) else if(curBlock->magic != MAGIC) { //Corrupt Heap + Heap_Dump(); _SysDebug("malloc: Corrupt Heap\n"); return NULL; } @@ -107,9 +118,12 @@ EXPORT void *malloc(size_t bytes) return NULL; } curBlock->magic = MAGIC; - return (void*)((uintptr_t)curBlock + sizeof(heap_head)); + DEBUGS("malloc(0x%x) = %p (extend) 0x%x", bytes, curBlock->data, bestSize); + return curBlock->data; } + heap_head *besthead = (void*)bestMatchAddr; + //Split Block? if(closestMatch - bestSize > BLOCK_SIZE) { heap_foot *foot; @@ -127,13 +141,15 @@ EXPORT void *malloc(size_t bytes) foot = (heap_foot*)(bestMatchAddr + closestMatch - sizeof(heap_foot)); foot->header = curBlock; - ((heap_head*)bestMatchAddr)->magic = MAGIC; //mark as used - return (void*)(bestMatchAddr + sizeof(heap_head)); + besthead->magic = MAGIC; //mark as used + DEBUGS("malloc(0x%x) = %p (split) 0x%x", bytes, besthead->data, bestSize); + return besthead->data; } //Don't Split the block - ((heap_head*)bestMatchAddr)->magic = MAGIC; - return (void*)(bestMatchAddr+sizeof(heap_head)); + besthead->magic = MAGIC; + DEBUGS("malloc(0x%x) = %p (reuse) 0x%x", bytes, besthead->data, besthead->size); + return besthead->data; } /** @@ -166,9 +182,10 @@ EXPORT void free(void *mem) return; head->magic = MAGIC_FREE; + DEBUGS("free(%p) : 0x%x bytes", mem, head->size); //Unify Right - if((intptr_t)head + head->size < (intptr_t)_heap_end) + if((uintptr_t)head + head->size < (uintptr_t)_heap_end) { heap_head *nextHead = (heap_head*)((intptr_t)head + head->size); if(nextHead->magic == MAGIC_FREE) { //Is the next block free @@ -177,7 +194,7 @@ EXPORT void free(void *mem) } } //Unify Left - if((intptr_t)head - sizeof(heap_foot) > (intptr_t)_heap_start) + if((uintptr_t)head - sizeof(heap_foot) > (uintptr_t)_heap_start) { heap_head *prevHead; heap_foot *prevFoot = (heap_foot *)((intptr_t)head - sizeof(heap_foot)); @@ -427,3 +444,25 @@ LOCAL uint brk(uintptr_t newpos) return ret; // Return old curpos } + +void Heap_Dump(void) +{ + heap_head *cur = _heap_start; + while( cur < (heap_head*)_heap_end ) + { + switch( cur->magic ) + { + case MAGIC: + _SysDebug("Used block %p[0x%x] - ptr=%p", cur, cur->size, cur->data); + break; + case MAGIC_FREE: + _SysDebug("Free block %p[0x%x] - ptr=%p", cur, cur->size, cur->data); + break; + default: + _SysDebug("Block %p bad magic (0x%x)", cur, cur->magic); + return ; + } + cur = (void*)( (char*)cur + cur->size ); + } +} +