/*
- * AcessOS Microkernel Version
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
* heap.c
+ * - Dynamic memory allocation
*/
#include <acess.h>
#include <mm_virt.h>
#include <heap_int.h>
+#include <limits.h>
-#define WARNINGS 1
-#define DEBUG_TRACE 0
-#define VERBOSE_DUMP 0
+#define WARNINGS 1 // Warn and dump on heap errors
+#define DEBUG_TRACE 0 // Enable tracing of allocations
+#define VERBOSE_DUMP 0 // Set to 1 to enable a verbose dump when heap errors are encountered
// === CONSTANTS ===
#define HEAP_INIT_SIZE 0x8000 // 32 KiB
// === PROTOTYPES ===
void Heap_Install(void);
-void *Heap_Extend(int Bytes);
+void *Heap_Extend(size_t 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_Dump(void);
+//void Heap_Deallocate(const char *File, int Line, void *Ptr);
+void Heap_Dump(int bVerbose);
void Heap_Stats(void);
// === GLOBALS ===
tMutex glHeap;
-void *gHeapStart;
-void *gHeapEnd;
+tHeapHead *gHeapStart;
+tHeapHead *gHeapEnd;
// === CODE ===
void Heap_Install(void)
{
- gHeapStart = (void*)MM_KHEAP_BASE;
- gHeapEnd = (void*)MM_KHEAP_BASE;
+ gHeapStart = (void*)MM_KHEAP_BASE;
+ gHeapEnd = gHeapStart;
Heap_Extend(HEAP_INIT_SIZE);
}
+static inline tHeapHead *Heap_NextHead(tHeapHead *Head) {
+ return (void*)( (char*)Head + Head->Size );
+}
+static inline tHeapFoot *Heap_ThisFoot(tHeapHead *Head) {
+ return (void*)( (char*)Head + Head->Size - sizeof(tHeapFoot) );
+}
+static inline tHeapFoot *Heap_PrevFoot(tHeapHead *Head) {
+ //ASSERT(Head != gHeapStart);
+ return (void*)( (char*)Head - sizeof(tHeapFoot) );
+}
+
/**
* \brief Extend the size of the heap
*/
-void *Heap_Extend(int Bytes)
+void *Heap_Extend(size_t Bytes)
{
- Uint i;
- tHeapHead *head = gHeapEnd;
- tHeapFoot *foot;
+
+ Debug("Heap_Extend(0x%x)", Bytes);
// Bounds Check
- if( (tVAddr)gHeapEnd == MM_KHEAP_MAX )
+ if( gHeapEnd == (tHeapHead*)MM_KHEAP_MAX ) {
+ Log_Error("Heap", "Heap limit reached (%p)", (void*)MM_KHEAP_MAX);
return NULL;
+ }
if( Bytes == 0 ) {
Log_Warning("Heap", "Heap_Extend called with Bytes=%i", Bytes);
return NULL;
}
+ const Uint pages = (Bytes + 0xFFF) >> 12;
+ tHeapHead *new_end = (void*)( (tVAddr)gHeapEnd + (pages << 12) );
// Bounds Check
- if( (tVAddr)gHeapEnd + ((Bytes+0xFFF)&~0xFFF) > MM_KHEAP_MAX ) {
-// Bytes = MM_KHEAP_MAX - (tVAddr)gHeapEnd;
+ if( new_end > (tHeapHead*)MM_KHEAP_MAX )
+ {
+ Log_Error("Heap", "Heap limit exceeded (%p)", (void*)new_end);
+ // TODO: Clip allocation to avaliable space, and have caller check returned block
return NULL;
}
// Heap expands in pages
- for( i = 0; i < (Bytes+0xFFF) >> 12; i ++ )
+ for( Uint i = 0; i < pages; i ++ )
{
if( !MM_Allocate( (tVAddr)gHeapEnd+(i<<12) ) )
{
- Warning("OOM - Heap_Extend");
+ Warning("OOM - Heap_Extend (%i bytes)");
+ Heap_Dump(1);
return NULL;
}
}
- // Increas heap end
- gHeapEnd = (Uint8*)gHeapEnd + (i << 12);
+ // Increase heap end
+ tHeapHead *head = gHeapEnd;
+ gHeapEnd = new_end;
// Create Block
head->Size = (Bytes+0xFFF)&~0xFFF;
head->Magic = MAGIC_FREE;
- foot = (void*)( (Uint)gHeapEnd - sizeof(tHeapFoot) );
+ tHeapFoot *foot = Heap_ThisFoot(head);
foot->Head = head;
foot->Magic = MAGIC_FOOT;
//Log("Heap_Merge: (Head=%p)", Head);
- thisFoot = (void*)( (Uint)Head + Head->Size - sizeof(tHeapFoot) );
- if((Uint)thisFoot > (Uint)gHeapEnd) return NULL;
+ thisFoot = Heap_ThisFoot(Head);
+ if( (void*)thisFoot > (void*)gHeapEnd )
+ return NULL;
// Merge Left (Down)
- foot = (void*)( (Uint)Head - sizeof(tHeapFoot) );
+ foot = Heap_PrevFoot(Head);
if( ((Uint)foot < (Uint)gHeapEnd && (Uint)foot > (Uint)gHeapStart)
&& foot->Head->Magic == MAGIC_FREE) {
foot->Head->Size += Head->Size; // Increase size
}
// Merge Right (Upwards)
- head = (void*)( (Uint)Head + Head->Size );
+ head = Heap_NextHead(Head);
if((Uint)head < (Uint)gHeapEnd && head->Magic == MAGIC_FREE)
{
Head->Size += head->Size;
- foot = (void*)( (Uint)Head + Head->Size - sizeof(tHeapFoot) );
+ foot = Heap_ThisFoot(Head);
foot->Head = Head; // Update Backlink
thisFoot->Head = NULL; // Clear old footer
thisFoot->Magic = 0;
*/
void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
{
- tHeapHead *head, *newhead;
+ tHeapHead *newhead;
tHeapFoot *foot, *newfoot;
tHeapHead *best = NULL;
- Uint bestSize = 0; // Speed hack
+ Uint bestSize = UINT_MAX; // Speed hack
size_t Bytes;
if( __Bytes == 0 ) {
- //return NULL; // TODO: Return a known un-mapped range.
- return INVLPTR;
+ return NULL; // TODO: Return a known un-mapped range.
+// return INVLPTR;
}
// Get required size
Mutex_Acquire(&glHeap);
// Traverse Heap
- for( head = gHeapStart;
- (Uint)head < (Uint)gHeapEnd;
- head = (void*)((Uint)head + head->Size)
- )
+ for( tHeapHead *head = gHeapStart; head < gHeapEnd; head = Heap_NextHead(head) )
{
// Alignment Check
#if POW2_SIZES
#endif
Mutex_Release(&glHeap); // Release spinlock
#if WARNINGS
- Log_Warning("Heap", "Size of heap address %p is invalid - not aligned (0x%x) [at paddr 0x%x]",
+ Log_Warning("Heap", "Size of heap address %p is invalid"
+ " - not aligned (0x%x) [at paddr 0x%x]",
head, head->Size, MM_GetPhysAddr(&head->Size));
- Heap_Dump();
+ Heap_Dump(VERBOSE_DUMP);
#endif
return NULL;
}
+ if( head->Size < MIN_SIZE ) {
+ Mutex_Release(&glHeap);
+ Log_Warning("Heap", "Size of heap address %p is invalid"
+ " - Too small (0x%x) [at paddr 0x%x]",
+ head, head->Size, MM_GetPhysAddr(&head->Size));
+ Heap_Dump(VERBOSE_DUMP);
+ return NULL;
+ }
+ if( head->Size > (2<<30) ) {
+ Mutex_Release(&glHeap);
+ Log_Warning("Heap", "Size of heap address %p is invalid"
+ " - Over 2GiB (0x%x) [at paddr 0x%x]",
+ head, head->Size, MM_GetPhysAddr(&head->Size));
+ Heap_Dump(VERBOSE_DUMP);
+ return NULL;
+ }
// Check if allocated
if(head->Magic == MAGIC_USED) continue;
#if WARNINGS
Log_Warning("Heap", "Magic of heap address %p is invalid (%p = 0x%x)",
head, &head->Magic, head->Magic);
- Heap_Dump();
+ Heap_Dump(VERBOSE_DUMP);
#endif
return NULL;
}
head->AllocateTime = now();
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Debug("[Heap ] Malloc'd %p (%i bytes), returning to %p",
- head->Data, head->Size, __builtin_return_address(0));
+ Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i",
+ head->Data, head->Size, File, Line);
#endif
return head->Data;
}
best = Heap_Extend( Bytes );
// Check for errors
if(!best) {
+ Warning("OOM when allocating 0x%x bytes", Bytes);
Mutex_Release(&glHeap); // Release spinlock
return NULL;
}
best->AllocateTime = now();
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Debug("[Heap ] Malloc'd %p (%i bytes), returning to %s:%i", best->Data, best->Size, File, Line);
+ Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i",
+ best->Data, best->Size, File, Line);
#endif
return best->Data;
}
}
// Split Block
- newhead = (void*)( (Uint)best + Bytes );
- newfoot = (void*)( (Uint)best + Bytes - sizeof(tHeapFoot) );
- foot = (void*)( (Uint)best + best->Size - sizeof(tHeapFoot) );
-
- newfoot->Head = best; // Create new footer
- newfoot->Magic = MAGIC_FOOT;
- newhead->Size = best->Size - Bytes; // Create new header
- newhead->Magic = MAGIC_FREE;
- foot->Head = newhead; // Update backlink in old footer
+ // - Save size for new block
+ size_t newsize = best->Size - Bytes;
+ // - Allocate beginning of old block
best->Size = Bytes; // Update size in old header
best->ValidSize = __Bytes;
best->Magic = MAGIC_USED; // Mark block as used
best->File = File;
best->Line = Line;
best->AllocateTime = now();
+ // - Create a new foot on old block
+ newfoot = Heap_ThisFoot(best);
+ newfoot->Head = best; // Create new footer
+ newfoot->Magic = MAGIC_FOOT;
+ // - Create a new header after resized old
+ newhead = Heap_NextHead(best);
+ newhead->Size = newsize;
+ newhead->Magic = MAGIC_FREE;
+ newhead->ValidSize = 0;
+ newhead->File = NULL;
+ newhead->Line = 0;
+ // - Update footer
+ foot = Heap_ThisFoot(newhead);
+ foot->Head = newhead;
Mutex_Release(&glHeap); // Release spinlock
#if DEBUG_TRACE
- Debug("[Heap ] Malloc'd %p (0x%x bytes), returning to %s:%i",
+ Log_Debug("Heap", "Malloc'd %p (0x%x bytes), returning to %s:%i",
best->Data, best->Size, File, Line);
#endif
return best->Data;
/**
* \brief Free an allocated memory block
*/
-void Heap_Deallocate(void *Ptr)
+void Heap_Deallocate(const char *File, int Line, void *Ptr)
{
- 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
- 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) ) {
+ if( (tVAddr)Ptr % sizeof(void*) != 0 ) {
Log_Warning("Heap", "free - Passed a non-aligned address (%p)", Ptr);
return;
}
// Sanity check
if((Uint)Ptr < (Uint)gHeapStart || (Uint)Ptr > (Uint)gHeapEnd)
{
- Log_Warning("Heap", "free - Passed a non-heap address by %p (%p < %p < %p)\n",
+ Log_Warning("Heap", "free - Passed a non-heap address by %p (%p < %p < %p)",
__builtin_return_address(0), gHeapStart, Ptr, gHeapEnd);
return;
}
// Check memory block - Header
- head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
+ tHeapHead *head = (void*)( (Uint)Ptr - sizeof(tHeapHead) );
if(head->Magic == MAGIC_FREE) {
- Log_Warning("Heap", "free - Passed a freed block (%p) by %p", head, __builtin_return_address(0));
+ Log_Warning("Heap", "free - Passed a freed block (%p) by %s:%i (was freed by %s:%i)",
+ head, File, Line,
+ head->File, head->Line);
return;
}
if(head->Magic != MAGIC_USED) {
}
// Check memory block - Footer
- foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
+ tHeapFoot *foot = Heap_ThisFoot(head);
if(foot->Head != head) {
Log_Warning("Heap", "free - Footer backlink is incorrect (%p, 0x%x)", head, foot->Head);
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_Warning("Heap", "free - Footer magic is invalid (%p, %p = 0x%x)",
+ head, &foot->Magic, foot->Magic);
Log_Notice("Heap", "Allocated by %s:%i", head->File, head->Line);
return;
}
+ #if DEBUG_TRACE
+ Log_Debug("Heap", "free: %p freed by %s:%i (%i old)",
+ Ptr, File, Line, now()-head->AllocateTime);
+ #endif
+
// Lock
Mutex_Acquire( &glHeap );
// Mark as free
head->Magic = MAGIC_FREE;
- //head->File = NULL;
- //head->Line = 0;
+ head->File = File;
+ head->Line = Line;
head->ValidSize = 0;
// Merge blocks
Heap_Merge( head );
if(newSize <= head->Size) return __ptr;
// Check if next block is free
- nextHead = (void*)( (Uint)head + head->Size );
+ nextHead = Heap_NextHead(head);
// Extend into next block
if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize)
{
Uint size = nextHead->Size + head->Size;
- foot = (void*)( (Uint)nextHead + nextHead->Size - sizeof(tHeapFoot) );
+ foot = Heap_ThisFoot(nextHead);
// Exact Fit
if(size == newSize) {
head->Size = newSize;
return __ptr;
}
// Create a new heap block
- nextHead = (void*)( (Uint)head + newSize );
- nextHead->Size = size - newSize;
- nextHead->Magic = MAGIC_FREE;
- foot->Head = nextHead; // Edit 2nd footer
- head->Size = newSize; // Edit first header
- head->File = File;
+ // - Update old with new information
+ head->Size = newSize;
+ head->File = File; // Kinda counts as a new allocation
head->Line = Line;
head->ValidSize = __size;
- // Create new footer
- foot = (void*)( (Uint)head + newSize - sizeof(tHeapFoot) );
+ // - Create new footer
+ foot = Heap_ThisFoot(head);
foot->Head = head;
foot->Magic = MAGIC_FOOT;
+ // - Create new header
+ nextHead = Heap_NextHead(head);
+ nextHead->Size = size - newSize;
+ nextHead->Magic = MAGIC_FREE;
+ // - Update old footer
+ foot->Head = nextHead;
return __ptr;
}
// Extend downwards?
- foot = (void*)( (Uint)head - sizeof(tHeapFoot) );
+ foot = Heap_PrevFoot(head);
nextHead = foot->Head;
if(nextHead->Magic == MAGIC_FREE && nextHead->Size+head->Size >= newSize)
{
// Inexact fit, split things up
if(size > newSize)
{
- // TODO
+ // TODO: Handle splitting of downwards blocks
Warning("[Heap ] TODO: Space efficient realloc when new size is smaller");
}
// Exact fit
- if(size >= newSize)
- {
- Uint oldDataSize;
- // Set 1st (new/lower) header
- nextHead->Magic = MAGIC_USED;
- nextHead->Size = newSize;
- nextHead->File = File;
- nextHead->Line = Line;
- nextHead->ValidSize = __size;
- // Get 2nd (old) footer
- foot = (void*)( (Uint)nextHead + newSize );
- foot->Head = nextHead;
- // Save old data size
- oldDataSize = head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead);
- // 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
+ Uint oldDataSize;
+ // Set 1st (new/lower) header
+ nextHead->Magic = MAGIC_USED;
+ nextHead->Size = newSize;
+ nextHead->File = File;
+ nextHead->Line = Line;
+ nextHead->ValidSize = __size;
+ // Get 2nd (old) footer
+ foot = Heap_ThisFoot(nextHead);
+ foot->Head = nextHead;
+ // Save old data size
+ oldDataSize = head->Size - sizeof(tHeapFoot) - sizeof(tHeapHead);
+ // Clear old header
+ head->Size = 0;
+ head->Magic = 0;
+ // Copy data
+ memmove(nextHead->Data, __ptr, oldDataSize);
+ // Return
+ return nextHead->Data;
}
// Well, darn
nextHead = Heap_Allocate( File, Line, __size );
+ if(!nextHead) return NULL;
nextHead -= 1;
nextHead->File = File;
nextHead->Line = Line;
*/
void Heap_Validate(void)
{
- Heap_Dump();
+ // Call dump non-verbosely.
+ // - If a heap error is detected, it'll print
+ Heap_Dump(0);
}
-#if WARNINGS
-void Heap_Dump(void)
+void Heap_Dump(int bVerbose)
{
tHeapHead *head, *badHead;
tHeapFoot *foot = NULL;
+ static int in_heap_dump;
+ if( in_heap_dump ) return;
+
+ in_heap_dump = 1;
+
head = gHeapStart;
while( (Uint)head < (Uint)gHeapEnd )
{
- foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
- #if VERBOSE_DUMP
- 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",
- (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
+ foot = Heap_ThisFoot(head);
+
+ if( bVerbose )
+ {
+ Log_Log("Heap", "%p (%P): 0x%08x (%i) %4C",
+ head, MM_GetPhysAddr(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",
+ (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
+ }
}
- #endif
// Sanity Check Header
if(head->Size == 0) {
break;
}
- #if VERBOSE_DUMP
- Log_Log("Heap", "");
- #endif
+ if( bVerbose )
+ {
+ Log_Log("Heap", "");
+ }
// All OK? Go to next
head = foot->NextHead;
}
// If the heap is valid, ok!
- if( (tVAddr)head == (tVAddr)gHeapEnd )
+ if( (tVAddr)head == (tVAddr)gHeapEnd ) {
+ in_heap_dump = 0;
return ;
+ }
// Check for a bad return
- if( (tVAddr)head >= (tVAddr)gHeapEnd )
+ if( (tVAddr)head >= (tVAddr)gHeapEnd ) {
+ in_heap_dump = 0;
return ;
+ }
- #if !VERBOSE_DUMP
- Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
- head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->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);
+ // If not verbose, we need to dump the failing block
+ if( !bVerbose )
+ {
+ Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
+ head, MM_GetPhysAddr(head), head->Size, head->ValidSize, &head->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);
+ }
+ Log_Log("Heap", "");
}
- Log_Log("Heap", "");
- #endif
badHead = head;
// Work backwards
- foot = (void*)( (tVAddr)gHeapEnd - sizeof(tHeapFoot) );
+ foot = Heap_PrevFoot(gHeapEnd);
Log_Log("Heap", "==== Going Backwards ==== (from %p)", foot);
head = foot->Head;
while( (tVAddr)head >= (tVAddr)badHead )
{
Log_Log("Heap", "%p (%P): 0x%08lx %i %4C",
- head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
+ head, MM_GetPhysAddr(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",
if(head == badHead) break;
- foot = (void*)( (tVAddr)head - sizeof(tHeapFoot) );
+ foot = Heap_PrevFoot(head);
head = foot->Head;
Log_Debug("Heap", "head=%p", head);
}
Panic("Heap_Dump - Heap is corrupted, kernel panic!");
}
-#endif
-#if 1
void Heap_Stats(void)
{
- tHeapHead *head;
int nBlocks = 0;
int nFree = 0;
int totalBytes = 0;
int maxAlloc=0, minAlloc=-1;
int avgAlloc, frag, overhead;
- for(head = gHeapStart;
- (Uint)head < (Uint)gHeapEnd;
- head = (void*)( (Uint)head + head->Size )
- )
+ for( tHeapHead *head = gHeapStart; head < gHeapEnd; head = Heap_NextHead(head) )
{
nBlocks ++;
totalBytes += head->Size;
#if 1
if( head->Magic == MAGIC_FREE )
Log_Debug("Heap", "%p (%P) - 0x%x free",
- head->Data, MM_GetPhysAddr((tVAddr)&head->Data), head->Size);
+ head->Data, MM_GetPhysAddr(&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,
+ head->Data, MM_GetPhysAddr(&head->Data), head->Size,
+ head->ValidSize, head->File, head->Line,
now() - head->AllocateTime
);
#endif
memset(sizeCounts, 0, nBlocks*sizeof(sizeCounts[0]));
- for(head = gHeapStart;
- (Uint)head < (Uint)gHeapEnd;
- head = (void*)( (Uint)head + head->Size )
- )
+ for(tHeapHead *head = gHeapStart; head < gHeapEnd; head = (void*)( (tVAddr)head + head->Size ) )
{
for( i = 0; i < nBlocks; i ++ ) {
if( sizeCounts[i].Size == 0 )
if( i == nBlocks ) continue;
sizeCounts[i].Size = head->Size;
sizeCounts[i].Count ++;
- #if 1
- //Log("Heap_Stats: %i %p - 0x%x bytes (%s) (%i)", nBlocks, head,
- // head->Size, (head->Magic==MAGIC_FREE?"FREE":"used"), i
- // );
- //Log("Heap_Stats: sizeCounts[%i] = {Size:0x%x, Count: %i}", i,
- // sizeCounts[i].Size, sizeCounts[i].Count);
+ #if 0
+ Log("Heap_Stats: %i %p - 0x%x bytes (%s) (%i)", nBlocks, head,
+ head->Size, (head->Magic==MAGIC_FREE?"FREE":"used"), i
+ );
+ Log("Heap_Stats: sizeCounts[%i] = {Size:0x%x, Count: %i}", i,
+ sizeCounts[i].Size, sizeCounts[i].Count);
#endif
}
}
#endif
}
-#endif
// === EXPORTS ===
EXPORT(Heap_Allocate);