X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fheap.c;h=1863f56f0284d49a803769e16d8dd31237d6aee7;hb=f87b0ab247466133ae7a6be7ac72b95462ab2b81;hp=75854b39197e04616089313975f127c25d1697b1;hpb=2eb3982679688ad61f5555d2a427d8317c5d8b17;p=tpg%2Facess2.git diff --git a/Kernel/heap.c b/Kernel/heap.c index 75854b39..1863f56f 100644 --- a/Kernel/heap.c +++ b/Kernel/heap.c @@ -11,7 +11,7 @@ // === CONSTANTS === #define HEAP_INIT_SIZE 0x8000 // 32 KiB -#define BLOCK_SIZE (sizeof(void*)) // 8 Machine Words +#define BLOCK_SIZE (sizeof(void*))*8 // 8 Machine Words #define COMPACT_HEAP 0 // Use 4 byte header? #define FIRST_FIT 0 @@ -20,12 +20,12 @@ #define MAGIC_USED 0x862B0505 // MAGIC_FOOT ^ MAGIC_FREE // === PROTOTYPES === -void Heap_Install(); +void Heap_Install(void); void *Heap_Extend(int Bytes); void *Heap_Merge(tHeapHead *Head); void *malloc(size_t Bytes); void free(void *Ptr); -void Heap_Dump(); +void Heap_Dump(void); // === GLOBALS === tSpinlock glHeap; @@ -33,7 +33,7 @@ void *gHeapStart; void *gHeapEnd; // === CODE === -void Heap_Install() +void Heap_Install(void) { gHeapStart = (void*)MM_KHEAP_BASE; gHeapEnd = (void*)MM_KHEAP_BASE; @@ -136,6 +136,8 @@ void *malloc(size_t Bytes) // Get required size Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1); + //if(glHeap) + // Debug("glHeap = %i", glHeap); // Lock Heap LOCK(&glHeap); @@ -147,11 +149,11 @@ void *malloc(size_t Bytes) { // Alignment Check if( head->Size & (BLOCK_SIZE-1) ) { + RELEASE(&glHeap); // Release spinlock #if WARNINGS Log_Warning("Heap", "Size of heap address %p is invalid not aligned (0x%x)", head, head->Size); Heap_Dump(); #endif - RELEASE(&glHeap); return NULL; } @@ -159,11 +161,11 @@ void *malloc(size_t Bytes) if(head->Magic == MAGIC_USED) continue; // Error check if(head->Magic != MAGIC_FREE) { + RELEASE(&glHeap); // Release spinlock #if WARNINGS Log_Warning("Heap", "Magic of heap address %p is invalid (0x%x)", head, head->Magic); Heap_Dump(); #endif - RELEASE(&glHeap); // Release spinlock return NULL; } @@ -205,6 +207,7 @@ void *malloc(size_t Bytes) } // Check size if(best->Size == Bytes) { + best->Magic = MAGIC_USED; // Mark block as used RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0)); @@ -345,8 +348,15 @@ void *realloc(void *__ptr, size_t __size) if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize) { Uint size = nextHead->Size + head->Size; + // Inexact fit, split things up + if(size > newSize) + { + // TODO + Warning("[Heap ] TODO: Space efficient realloc when new size is smaller"); + } + // Exact fit - if(size == newSize) + if(size >= newSize) { Uint oldDataSize; // Set 1st (new/lower) header @@ -360,11 +370,27 @@ void *realloc(void *__ptr, size_t __size) // Clear old header head->Size = 0; head->Magic = 0; + // Copy data memcpy(nextHead->Data, __ptr, oldDataSize); + // Return + return nextHead->Data; } + // On to the expensive then } - return NULL; + // Well, darn + nextHead = malloc( __size ); + nextHead -= 1; + + memcpy( + nextHead->Data, + __ptr, + head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead) + ); + + free(__ptr); + + return nextHead->Data; } /** @@ -402,7 +428,7 @@ int IsHeap(void *Ptr) } #if WARNINGS -void Heap_Dump() +void Heap_Dump(void) { tHeapHead *head; tHeapFoot *foot; @@ -411,7 +437,8 @@ void Heap_Dump() while( (Uint)head < (Uint)gHeapEnd ) { foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); - Log_Log("Heap", "%p (0x%x): 0x%08lx 0x%lx", head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic); + Log_Log("Heap", "%p (0x%x): 0x%08lx 0x%lx", + head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic); Log_Log("Heap", "%p 0x%lx", foot->Head, foot->Magic); Log_Log("Heap", "");