Kernel - Fixed syscall parameter orders
[tpg/acess2.git] / Kernel / heap.c
index aa08100..fc99f56 100644 (file)
@@ -7,7 +7,7 @@
 #include <heap_int.h>
 
 #define WARNINGS       1
-#define        DEBUG_TRACE     1
+#define        DEBUG_TRACE     0
 #define        VERBOSE_DUMP    0
 
 // === CONSTANTS ===
 void   Heap_Install(void);
 void   *Heap_Extend(int Bytes);
 void   *Heap_Merge(tHeapHead *Head);
-void   *Heap_Allocate(const char *File, int Line, size_t Bytes);
-void   *Heap_AllocateZero(const char *File, int Line, size_t Bytes);
-void   *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes);
-void   Heap_Deallocate(void *Ptr);
+//void *Heap_Allocate(const char *File, int Line, size_t Bytes);
+//void *Heap_AllocateZero(const char *File, int Line, size_t Bytes);
+//void *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes);
+//void Heap_Deallocate(void *Ptr);
 void   Heap_Dump(void);
 void   Heap_Stats(void);
 
@@ -62,6 +62,11 @@ void *Heap_Extend(int Bytes)
        if( (tVAddr)gHeapEnd == MM_KHEAP_MAX )
                return NULL;
        
+       if( Bytes == 0 ) {
+               Log_Warning("Heap", "Heap_Extend called with Bytes=%i", Bytes);
+               return NULL;
+       }
+       
        // Bounds Check
        if( (tVAddr)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) {
                Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd;
@@ -69,11 +74,17 @@ void *Heap_Extend(int Bytes)
        }
        
        // Heap expands in pages
-       for(i=0;i<(Bytes+0xFFF)>>12;i++)
-               MM_Allocate( (tVAddr)gHeapEnd+(i<<12) );
+       for( i = 0; i < (Bytes+0xFFF) >> 12; i ++ )
+       {
+               if( !MM_Allocate( (tVAddr)gHeapEnd+(i<<12) ) )
+               {
+                       Warning("OOM - Heap_Extend");
+                       return NULL;
+               }
+       }
        
        // Increas heap end
-       gHeapEnd += i << 12;
+       gHeapEnd = (Uint8*)gHeapEnd + (i << 12);
        
        // Create Block
        head->Size = (Bytes+0xFFF)&~0xFFF;
@@ -143,6 +154,11 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
        tHeapHead       *best = NULL;
        Uint    bestSize = 0;   // Speed hack
        size_t  Bytes;
+
+       if( __Bytes == 0 ) {
+               //return NULL;  // TODO: Return a known un-mapped range.
+               return INVLPTR;
+       }
        
        // Get required size
        #if POW2_SIZES
@@ -195,9 +211,11 @@ 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;
                }
@@ -230,9 +248,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;
                }
@@ -253,11 +273,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->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;
@@ -269,12 +289,15 @@ void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
  */
 void Heap_Deallocate(void *Ptr)
 {
-       tHeapHead       *head;
+       tHeapHead       *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
        tHeapFoot       *foot;
        
+       // INVLPTR is returned from Heap_Allocate when the allocation
+       // size is zero.
+       if( Ptr == INVLPTR )    return;
+       
        #if DEBUG_TRACE
-       Log_Log("Heap", "free: Ptr = %p", Ptr);
-       Log_Log("Heap", "free: Returns to %p", __builtin_return_address(0));
+       Debug("[Heap   ] free: %p freed by %p (%i old)", Ptr, __builtin_return_address(0), now()-head->AllocateTime);
        #endif
        
        // Alignment Check
@@ -299,7 +322,7 @@ void Heap_Deallocate(void *Ptr)
        }
        if(head->Magic != MAGIC_USED) {
                Log_Warning("Heap", "free - Magic value is invalid (%p, 0x%x)", head, head->Magic);
-               Log_Notice("Heap", "Allocated %s:%i", head->File, head->Line);
+               Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line);
                return;
        }
        
@@ -307,12 +330,12 @@ void Heap_Deallocate(void *Ptr)
        foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
        if(foot->Head != head) {
                Log_Warning("Heap", "free - Footer backlink is incorrect (%p, 0x%x)", head, foot->Head);
-               Log_Notice("Heap", "Allocated %s:%i", head->File, head->Line);
+               Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line);
                return;
        }
        if(foot->Magic != MAGIC_FOOT) {
                Log_Warning("Heap", "free - Footer magic is invalid (%p, %p = 0x%x)", head, &foot->Magic, foot->Magic);
-               Log_Notice("Heap", "Allocated %s:%i", head->File, head->Line);
+               Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line);
                return;
        }
        
@@ -340,7 +363,7 @@ void Heap_Deallocate(void *Ptr)
  */
 void *Heap_Reallocate(const char *File, int Line, void *__ptr, size_t __size)
 {
-       tHeapHead       *head = (void*)( (Uint)__ptr-8 );
+       tHeapHead       *head = (void*)( (Uint)__ptr-sizeof(tHeapHead) );
        tHeapHead       *nextHead;
        tHeapFoot       *foot;
        Uint    newSize = (__size + sizeof(tHeapFoot)+sizeof(tHeapHead)+MIN_SIZE-1)&~(MIN_SIZE-1);
@@ -478,11 +501,18 @@ int Heap_IsHeapAddr(void *Ptr)
        return 1;
 }
 
+/**
+ */
+void Heap_Validate(void)
+{
+       Heap_Dump();
+}
+
 #if WARNINGS
 void Heap_Dump(void)
 {
        tHeapHead       *head, *badHead;
-       tHeapFoot       *foot;
+       tHeapFoot       *foot = NULL;
        
        head = gHeapStart;
        while( (Uint)head < (Uint)gHeapEnd )
@@ -530,14 +560,19 @@ void Heap_Dump(void)
                head = foot->NextHead;
        }
        
+       // If the heap is valid, ok!
+       if( (tVAddr)head == (tVAddr)gHeapEnd )
+               return ;
+       
        // Check for a bad return
        if( (tVAddr)head >= (tVAddr)gHeapEnd )
                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", "Backlink = %p %4C", foot->Head, &foot->Magic);
        if(head->File) {
                Log_Log("Heap", "%sowned by %s:%i",
                        (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
@@ -554,7 +589,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)
@@ -593,6 +628,8 @@ void Heap_Dump(void)
                head = foot->Head;
                Log_Debug("Heap", "head=%p", head);
        }
+       
+       Panic("Heap_Dump - Heap is corrupted, kernel panic!");
 }
 #endif
 
@@ -631,17 +668,29 @@ void Heap_Stats(void)
                
                // Print the block info?
                #if 1
-               Log_Debug("Heap", "%p - 0x%x Owned by %s:%i",
-                       head, head->Size, 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(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
                );

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