X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fheap.c;h=75854b39197e04616089313975f127c25d1697b1;hb=2eb3982679688ad61f5555d2a427d8317c5d8b17;hp=f42d59f8001bfe4933fb72c0bf9624f3aab60dd0;hpb=a4ce2e60f783c9e71447edc03f20f937b8abf35a;p=tpg%2Facess2.git diff --git a/Kernel/heap.c b/Kernel/heap.c index f42d59f8..75854b39 100644 --- a/Kernel/heap.c +++ b/Kernel/heap.c @@ -10,8 +10,6 @@ #define DEBUG_TRACE 0 // === CONSTANTS === -#define HEAP_BASE 0xE0800000 -#define HEAP_MAX 0xF0000000 // 120MiB, Plenty #define HEAP_INIT_SIZE 0x8000 // 32 KiB #define BLOCK_SIZE (sizeof(void*)) // 8 Machine Words #define COMPACT_HEAP 0 // Use 4 byte header? @@ -30,7 +28,7 @@ void free(void *Ptr); void Heap_Dump(); // === GLOBALS === - int giHeapSpinlock; +tSpinlock glHeap; void *gHeapStart; void *gHeapEnd; @@ -53,18 +51,18 @@ void *Heap_Extend(int Bytes) tHeapFoot *foot; // Bounds Check - if( (Uint)gHeapEnd == MM_KHEAP_MAX ) + if( (tVAddr)gHeapEnd == MM_KHEAP_MAX ) return NULL; // Bounds Check - if( (Uint)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) { - Bytes = MM_KHEAP_MAX - (Uint)gHeapEnd; + if( (tVAddr)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) { + Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd; return NULL; } // Heap expands in pages for(i=0;i<(Bytes+0xFFF)>>12;i++) - MM_Allocate( (Uint)gHeapEnd+(i<<12) ); + MM_Allocate( (tVAddr)gHeapEnd+(i<<12) ); // Increas heap end gHeapEnd += i << 12; @@ -76,7 +74,6 @@ void *Heap_Extend(int Bytes) foot->Head = head; foot->Magic = MAGIC_FOOT; - //Log(" Heap_Extend: head = %p", head); return Heap_Merge(head); // Merge with previous block } @@ -97,7 +94,7 @@ void *Heap_Merge(tHeapHead *Head) // Merge Left (Down) foot = (void*)( (Uint)Head - sizeof(tHeapFoot) ); - if( ((Uint)foot < (Uint)gHeapEnd && (Uint)foot > HEAP_BASE) + if( ((Uint)foot < (Uint)gHeapEnd && (Uint)foot > (Uint)gHeapStart) && foot->Head->Magic == MAGIC_FREE) { foot->Head->Size += Head->Size; // Increase size thisFoot->Head = foot->Head; // Change backlink @@ -140,7 +137,7 @@ void *malloc(size_t Bytes) Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1); // Lock Heap - LOCK(&giHeapSpinlock); + LOCK(&glHeap); // Traverse Heap for( head = gHeapStart; @@ -151,9 +148,10 @@ void *malloc(size_t Bytes) // Alignment Check if( head->Size & (BLOCK_SIZE-1) ) { #if WARNINGS - Warning("Size of heap address %p is invalid not aligned (0x%x)", head, head->Size); + Log_Warning("Heap", "Size of heap address %p is invalid not aligned (0x%x)", head, head->Size); Heap_Dump(); #endif + RELEASE(&glHeap); return NULL; } @@ -162,10 +160,10 @@ void *malloc(size_t Bytes) // Error check if(head->Magic != MAGIC_FREE) { #if WARNINGS - Warning("Magic of heap address %p is invalid (0x%x)", head, head->Magic); + Log_Warning("Heap", "Magic of heap address %p is invalid (0x%x)", head, head->Magic); Heap_Dump(); #endif - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock return NULL; } @@ -175,11 +173,11 @@ void *malloc(size_t Bytes) // Perfect fit if(head->Size == Bytes) { head->Magic = MAGIC_USED; - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE - LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); + Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", head->Data, head->Size, __builtin_return_address(0)); #endif - return best->Data; + return head->Data; } // Break out of loop @@ -202,14 +200,14 @@ void *malloc(size_t Bytes) best = Heap_Extend( Bytes ); // Check for errors if(!best) { - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock return NULL; } // Check size if(best->Size == Bytes) { - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE - LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); + Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0)); #endif return best->Data; } @@ -228,9 +226,9 @@ void *malloc(size_t Bytes) best->Size = Bytes; // Update size in old header best->Magic = MAGIC_USED; // Mark block as used - RELEASE(&giHeapSpinlock); // Release spinlock + RELEASE(&glHeap); // Release spinlock #if DEBUG_TRACE - LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0)); + Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0)); #endif return best->Data; } @@ -245,47 +243,48 @@ void free(void *Ptr) tHeapFoot *foot; #if DEBUG_TRACE - LOG("Ptr = %p", Ptr); - LOG("Returns to %p", __builtin_return_address(0)); + Log_Log("Heap", "free: Ptr = %p", Ptr); + Log_Log("Heap", "free: Returns to %p", __builtin_return_address(0)); #endif // Alignment Check if( (Uint)Ptr & (sizeof(Uint)-1) ) { - Warning("free - Passed a non-aligned address (%p)", Ptr); + Log_Warning("Heap", "free - Passed a non-aligned address (%p)", Ptr); return; } // Sanity check if((Uint)Ptr < (Uint)gHeapStart || (Uint)Ptr > (Uint)gHeapEnd) { - Warning("free - Passed a non-heap address (%p)\n", Ptr); + Log_Warning("Heap", "free - Passed a non-heap address (%p < %p < %p)\n", + gHeapStart, Ptr, gHeapEnd); return; } // Check memory block - Header head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); if(head->Magic == MAGIC_FREE) { - Warning("free - Passed a freed block (%p) by %p", head, __builtin_return_address(0)); + Log_Warning("Heap", "free - Passed a freed block (%p) by %p", head, __builtin_return_address(0)); return; } if(head->Magic != MAGIC_USED) { - Warning("free - Magic value is invalid (%p, 0x%x)\n", head, head->Magic); + Log_Warning("Heap", "free - Magic value is invalid (%p, 0x%x)\n", head, head->Magic); return; } // Check memory block - Footer foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); if(foot->Head != head) { - Warning("free - Footer backlink is incorrect (%p, 0x%x)\n", head, foot->Head); + Log_Warning("Heap", "free - Footer backlink is incorrect (%p, 0x%x)\n", head, foot->Head); return; } if(foot->Magic != MAGIC_FOOT) { - Warning("free - Footer magic is invalid (%p, %p = 0x%x)\n", head, &foot->Magic, foot->Magic); + Log_Warning("Heap", "free - Footer magic is invalid (%p, %p = 0x%x)\n", head, &foot->Magic, foot->Magic); return; } // Lock - LOCK( &giHeapSpinlock ); + LOCK( &glHeap ); // Mark as free head->Magic = MAGIC_FREE; @@ -293,7 +292,7 @@ void free(void *Ptr) Heap_Merge( head ); // Release - RELEASE( &giHeapSpinlock ); + RELEASE( &glHeap ); } /** @@ -386,13 +385,14 @@ void *calloc(size_t num, size_t size) /** * \fn int IsHeap(void *Ptr) - * \brief Checks if an address is a heap address + * \brief Checks if an address is a heap pointer */ int IsHeap(void *Ptr) { tHeapHead *head; if((Uint)Ptr < (Uint)gHeapStart) return 0; if((Uint)Ptr > (Uint)gHeapEnd) return 0; + if((Uint)Ptr & (sizeof(Uint)-1)) return 0; head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); if(head->Magic != MAGIC_USED && head->Magic != MAGIC_FREE) @@ -411,31 +411,31 @@ void Heap_Dump() while( (Uint)head < (Uint)gHeapEnd ) { foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) ); - Log("%p (0x%x): 0x%08lx 0x%lx", head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic); - Log("%p 0x%lx", foot->Head, foot->Magic); - Log(""); + 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", ""); // Sanity Check Header if(head->Size == 0) { - Log("HALTED - Size is zero"); + Log_Warning("Heap", "HALTED - Size is zero"); break; } if(head->Size & (BLOCK_SIZE-1)) { - Log("HALTED - Size is malaligned"); + Log_Warning("Heap", "HALTED - Size is malaligned"); break; } if(head->Magic != MAGIC_FREE && head->Magic != MAGIC_USED) { - Log("HALTED - Head Magic is Bad"); + Log_Warning("Heap", "HALTED - Head Magic is Bad"); break; } // Check footer if(foot->Magic != MAGIC_FOOT) { - Log("HALTED - Foot Magic is Bad"); + Log_Warning("Heap", "HALTED - Foot Magic is Bad"); break; } if(head != foot->Head) { - Log("HALTED - Footer backlink is invalid"); + Log_Warning("Heap", "HALTED - Footer backlink is invalid"); break; }