Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / Kernel / heap.c
index c440b18..eefd13c 100644 (file)
@@ -49,7 +49,6 @@ void Heap_Install(void)
 }
 
 /**
- * \fn void *Heap_Extend(int Bytes)
  * \brief Extend the size of the heap
  */
 void *Heap_Extend(int Bytes)
@@ -69,7 +68,7 @@ void *Heap_Extend(int Bytes)
        
        // Bounds Check
        if( (tVAddr)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) {
-               Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd;
+//             Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd;
                return NULL;
        }
        
@@ -97,7 +96,6 @@ void *Heap_Extend(int Bytes)
 }
 
 /**
- * \fn void *Heap_Merge(tHeapHead *Head)
  * \brief Merges two ajacent heap blocks
  */
 void *Heap_Merge(tHeapHead *Head)
@@ -142,10 +140,9 @@ void *Heap_Merge(tHeapHead *Head)
 }
 
 /**
- * \brief Allocate memory from the heap
  * \param File Allocating source file
  * \param Line Source line
- * \param Bytes        Size of region to allocate
+ * \param __Bytes      Size of region to allocate
  */
 void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
 {
@@ -197,7 +194,8 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
                if(head->Magic != MAGIC_FREE)   {
                        Mutex_Release(&glHeap); // Release spinlock
                        #if WARNINGS
-                       Log_Warning("Heap", "Magic of heap address %p is invalid (0x%x)", head, head->Magic);
+                       Log_Warning("Heap", "Magic of heap address %p is invalid (%p = 0x%x)",
+                               head, &head->Magic, head->Magic);
                        Heap_Dump();
                        #endif
                        return NULL;
@@ -211,9 +209,12 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
                        head->Magic = MAGIC_USED;
                        head->File = File;
                        head->Line = Line;
+                       head->ValidSize = __Bytes;
+                       head->AllocateTime = now();
                        Mutex_Release(&glHeap); // Release spinlock
                        #if DEBUG_TRACE
-                       Log("[Heap   ] Malloc'd %p (%i bytes), returning to %p", head->Data, head->Size,  __builtin_return_address(0));
+                       Debug("[Heap   ] Malloc'd %p (%i bytes), returning to %p",
+                               head->Data, head->Size,  __builtin_return_address(0));
                        #endif
                        return head->Data;
                }
@@ -246,9 +247,11 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
                        best->Magic = MAGIC_USED;       // Mark block as used
                        best->File = File;
                        best->Line = Line;
+                       best->ValidSize = __Bytes;
+                       best->AllocateTime = now();
                        Mutex_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));
+                       Debug("[Heap   ] Malloc'd %p (%i bytes), returning to %s:%i", best->Data, best->Size, File, Line);
                        #endif
                        return best->Data;
                }
@@ -269,34 +272,32 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
        best->Magic = MAGIC_USED;       // Mark block as used
        best->File = File;
        best->Line = Line;
+       best->AllocateTime = now();
        
        Mutex_Release(&glHeap); // Release spinlock
        #if DEBUG_TRACE
-       Log_Debug("Heap", "newhead(%p)->Size = 0x%x", newhead, newhead->Size);
-       Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i",
+       Debug("[Heap   ] Malloc'd %p (0x%x bytes), returning to %s:%i",
                best->Data, best->Size, File, Line);
        #endif
        return best->Data;
 }
 
 /**
- * \fn void Heap_Deallocate(void *Ptr)
  * \brief Free an allocated memory block
  */
 void Heap_Deallocate(void *Ptr)
 {
-       tHeapHead       *head;
+       tHeapHead       *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
        tHeapFoot       *foot;
        
-       #if DEBUG_TRACE
-       Log_Log("Heap", "free: Ptr = %p", Ptr);
-       Log_Log("Heap", "free: Returns to %p", __builtin_return_address(0));
-       #endif
-       
        // INVLPTR is returned from Heap_Allocate when the allocation
        // size is zero.
        if( Ptr == INVLPTR )    return;
        
+       #if DEBUG_TRACE
+       Debug("[Heap   ] free: %p freed by %p (%i old)", Ptr, __builtin_return_address(0), now()-head->AllocateTime);
+       #endif
+       
        // Alignment Check
        if( (Uint)Ptr & (sizeof(Uint)-1) ) {
                Log_Warning("Heap", "free - Passed a non-aligned address (%p)", Ptr);
@@ -306,8 +307,8 @@ void Heap_Deallocate(void *Ptr)
        // Sanity check
        if((Uint)Ptr < (Uint)gHeapStart || (Uint)Ptr > (Uint)gHeapEnd)
        {
-               Log_Warning("Heap", "free - Passed a non-heap address (%p < %p < %p)\n",
-                       gHeapStart, Ptr, gHeapEnd);
+               Log_Warning("Heap", "free - Passed a non-heap address by %p (%p < %p < %p)\n",
+                       __builtin_return_address(0), gHeapStart, Ptr, gHeapEnd);
                return;
        }
        
@@ -516,8 +517,8 @@ void Heap_Dump(void)
        {               
                foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
                #if VERBOSE_DUMP
-               Log_Log("Heap", "%p (0x%llx): 0x%08lx (%i) %4C",
-                       head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
+               Log_Log("Heap", "%p (0x%P): 0x%08x (%i) %4C",
+                       head, MM_GetPhysAddr((tVAddr)head), head->Size, head->ValidSize, &head->Magic);
                Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
                if(head->File) {
                        Log_Log("Heap", "%sowned by %s:%i",
@@ -566,9 +567,10 @@ void Heap_Dump(void)
                return ;
 
        #if !VERBOSE_DUMP
-       Log_Log("Heap", "%p (0x%llx): 0x%08lx %i %4C",
+       Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
                head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
-       Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
+       if(foot)
+               Log_Log("Heap", "Foot %p = {Head:%p,Magic:%4C}", foot, foot->Head, &foot->Magic);
        if(head->File) {
                Log_Log("Heap", "%sowned by %s:%i",
                        (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
@@ -585,7 +587,7 @@ void Heap_Dump(void)
        head = foot->Head;
        while( (tVAddr)head >= (tVAddr)badHead )
        {
-               Log_Log("Heap", "%p (0x%llx): 0x%08lx %i %4C",
+               Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
                        head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
                Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
                if(head->File)
@@ -664,17 +666,32 @@ void Heap_Stats(void)
                
                // Print the block info?
                #if 1
-               Log_Debug("Heap", "%p - 0x%x (%i) Owned by %s:%i",
-                       head, head->Size, head->ValidSize, head->File, head->Line);
+               if( head->Magic == MAGIC_FREE )
+                       Log_Debug("Heap", "%p (%P) - 0x%x free",
+                               head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size);
+               else
+                       Log_Debug("Heap", "%p (%P) - 0x%x (%i) Owned by %s:%i (%lli ms old)",
+                               head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size, head->ValidSize, head->File, head->Line,
+                               now() - head->AllocateTime
+                               );
                #endif
        }
 
        Log_Log("Heap", "%i blocks (0x%x bytes)", nBlocks, totalBytes);
        Log_Log("Heap", "%i free blocks (0x%x bytes)", nFree, freeBytes);
-       frag = (nFree-1)*10000/nBlocks;
+       if(nBlocks != 0)
+               frag = (nFree-1)*10000/nBlocks;
+       else
+               frag = 0;
        Log_Log("Heap", "%i.%02i%% Heap Fragmentation", frag/100, frag%100);
-       avgAlloc = (totalBytes-freeBytes)/(nBlocks-nFree);
-       overhead = (sizeof(tHeapFoot)+sizeof(tHeapHead))*10000/avgAlloc;
+       if(nBlocks <= nFree)
+               avgAlloc = 0;
+       else
+               avgAlloc = (totalBytes-freeBytes)/(nBlocks-nFree);
+       if(avgAlloc != 0)
+               overhead = (sizeof(tHeapFoot)+sizeof(tHeapHead))*10000/avgAlloc;
+       else
+               overhead = 0;
        Log_Log("Heap", "Average allocation: %i bytes, Average Overhead: %i.%02i%%",
                avgAlloc, overhead/100, overhead%100
                );
@@ -683,6 +700,7 @@ void Heap_Stats(void)
        
        // Scan and get distribution
        #if 1
+       if(nBlocks > 0)
        {
                struct {
                        Uint    Size;

UCC git Repository :: git.ucc.asn.au