650 lines
15 KiB
C
650 lines
15 KiB
C
/*
|
|
* Block.c
|
|
*
|
|
* Routines to allocate memory from one large block.
|
|
* Any memory allocated is only available to reallocated after
|
|
* the whole block has been reset.
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
/* Allow frame header files to be singly included */
|
|
#define FRAME_LIB_INCLUDE
|
|
|
|
// memory usage printf's
|
|
#define DEBUG_GROUP0
|
|
|
|
#include "types.h"
|
|
#include "debug.h"
|
|
#include "mem.h"
|
|
#include "heap.h"
|
|
#include "treap.h"
|
|
#include "treapint.h"
|
|
#include "memint.h"
|
|
#include "listmacs.h"
|
|
|
|
#include "block.h"
|
|
|
|
/* What functions to use for the real malloc and free */
|
|
|
|
#define RMALLOC malloc
|
|
#define RFREE free
|
|
|
|
|
|
/* Whether allocated memory is initialised to a value and whether the memory
|
|
* is trashed before it is freed.
|
|
* This is done automatically by Visual C's memory routines.
|
|
*/
|
|
#define MEMORY_SET TRUE
|
|
|
|
// the filename and line number of the last call to the block functions
|
|
STRING *pCallFileName;
|
|
SDWORD callLine;
|
|
|
|
// the list of allocated blocks
|
|
static BLOCK_HEAP *psBlockList=NULL;
|
|
|
|
// initialise the block system
|
|
BOOL blkInitialise(void)
|
|
{
|
|
ASSERT( psBlockList==NULL, "blkInitialise: Blocks already initialised" ); // blkShutDown() needs to be called
|
|
|
|
LIST_INIT(psBlockList);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// shutdown the block system
|
|
void blkShutDown(void)
|
|
{
|
|
BLOCK_HEAP *psNext;
|
|
|
|
if (psBlockList)
|
|
{
|
|
debug( LOG_NEVER, "blkShutDown: blocks still allocated:\n" );
|
|
while (psBlockList)
|
|
{
|
|
psNext = psBlockList->psNext;
|
|
blkDestroy(psBlockList);
|
|
psBlockList = psNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Note the call position for a blkAlloc or blkFree
|
|
void blkCallPos(STRING *pFileName, SDWORD line)
|
|
{
|
|
pCallFileName = pFileName;
|
|
callLine = line;
|
|
}
|
|
|
|
// Create a new block heap
|
|
BOOL blkCreate(BLOCK_HEAP **ppsHeap, SDWORD init, SDWORD ext)
|
|
{
|
|
|
|
debug( LOG_NEVER, "BLKCREATE CALLED !!!!!!!!!!!!!!!!!!!!!!\n" );
|
|
*ppsHeap = (BLOCK_HEAP*)RMALLOC(sizeof(BLOCK_HEAP));
|
|
if (!*ppsHeap)
|
|
{
|
|
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
|
abort();
|
|
return FALSE;
|
|
}
|
|
(*ppsHeap)->psBlocks = (BLOCK_HEAP_MEM*)RMALLOC(sizeof(BLOCK_HEAP_MEM));
|
|
if (!(*ppsHeap)->psBlocks)
|
|
{
|
|
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
|
abort();
|
|
return FALSE;
|
|
}
|
|
(*ppsHeap)->psBlocks->pMem = (UBYTE*)RMALLOC(init);
|
|
if (!(*ppsHeap)->psBlocks->pMem)
|
|
{
|
|
|
|
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
|
abort();
|
|
return FALSE;
|
|
}
|
|
|
|
(*ppsHeap)->init = init;
|
|
(*ppsHeap)->ext = ext;
|
|
(*ppsHeap)->psBlocks->size = init;
|
|
(*ppsHeap)->psBlocks->pFree = (*ppsHeap)->psBlocks->pMem;
|
|
(*ppsHeap)->psBlocks->psNext = NULL;
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
(*ppsHeap)->pFileName = pCallFileName;
|
|
(*ppsHeap)->line = callLine;
|
|
(*ppsHeap)->psMemTreap = NULL;
|
|
(*ppsHeap)->free = FALSE;
|
|
(*ppsHeap)->TotalAllocated=0;
|
|
#endif
|
|
|
|
LIST_ADD(psBlockList, *ppsHeap);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Release a block heap
|
|
void blkDestroy(BLOCK_HEAP *psHeap)
|
|
{
|
|
BLOCK_HEAP_MEM *psCurr, *psNext;
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
if (psHeap->psMemTreap != NULL)
|
|
{
|
|
debug( LOG_NEVER, "blkDestroy: %s at %d: memory allocated :\n", psHeap->pFileName, psHeap->line );
|
|
memRecReport(psHeap->psMemTreap);
|
|
}
|
|
#endif
|
|
|
|
LIST_REMOVE(psBlockList, psHeap, BLOCK_HEAP);
|
|
|
|
for(psCurr=psHeap->psBlocks; psCurr; psCurr=psNext)
|
|
{
|
|
RFREE(psCurr->pMem);
|
|
psNext = psCurr->psNext;
|
|
RFREE(psCurr);
|
|
}
|
|
RFREE(psHeap);
|
|
}
|
|
|
|
void memMemoryDump(MEM_NODE *Node);
|
|
|
|
|
|
void blkPrintDetails(BLOCK_HEAP *psHeap)
|
|
{
|
|
if (psHeap!=NULL)
|
|
{
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
UDWORD Left = (UDWORD)((psHeap->psBlocks->pMem)+(psHeap->psBlocks->size)-(psHeap->psBlocks->pFree));
|
|
debug( LOG_NEVER, "ptr=%p init=%d ext=%d used=%d (Start=$%p Free=$%p Left=%d)\n", psHeap,psHeap->init, psHeap->ext,psHeap->TotalAllocated, psHeap->psBlocks->pMem, psHeap->psBlocks->pFree, Left );
|
|
memMemoryDump(psHeap->psMemTreap);
|
|
#else
|
|
debug( LOG_NEVER, "ptr=%p init=%d ext=%d\n", psHeap, psHeap->init, psHeap->ext );
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
debug( LOG_NEVER, "NULL POINTER IN BLOCK LIST\n" );
|
|
}
|
|
|
|
}
|
|
|
|
// report on the blocks
|
|
void blkReport(void)
|
|
{
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
UDWORD BlockNumber=0;
|
|
BLOCK_HEAP *psCurHeap;
|
|
|
|
debug( LOG_NEVER, "\n\nBlock Report. Current Block=%p:\n", memGetBlockHeap() );
|
|
|
|
psCurHeap=psBlockList;
|
|
|
|
while (psCurHeap)
|
|
{
|
|
debug( LOG_NEVER, "Block %d)",BlockNumber++ );
|
|
blkPrintDetails(psCurHeap);
|
|
|
|
psCurHeap = psCurHeap->psNext;
|
|
}
|
|
debug( LOG_NEVER, "\n\n" );
|
|
#endif
|
|
}
|
|
|
|
#if(0) // no longer used - uploaded in small chunks
|
|
// This is a special free that checks to see if we can free up the memory
|
|
// We can only do this if it is the last allocated memory in the block
|
|
//
|
|
// This can be used for scratch memory ... Critical on the Playstation where memory is so tight
|
|
//
|
|
// - e.g. The sound data must be stored as one 400k file. This must be loaded into scratch memory
|
|
// we clearly do not have 400k of spare memory around.
|
|
//
|
|
//
|
|
// Returns true or false
|
|
//
|
|
BOOL blkSpecialFree(BLOCK_HEAP *psHeap, void *Ptr)
|
|
{
|
|
BLOCK_HEAP_MEM *psCurr;
|
|
|
|
UDWORD RequestedFreeMem=(UDWORD)Ptr;
|
|
|
|
for(psCurr = psHeap->psBlocks; psCurr; psCurr = psCurr->psNext)
|
|
{
|
|
|
|
if ((UDWORD)psCurr->pLastAllocated == RequestedFreeMem)
|
|
{
|
|
#ifdef DEBUG_BLOCK
|
|
|
|
UDWORD BlockSize=((UDWORD)psCurr->pFree)-RequestedFreeMem;
|
|
debug( LOG_NEVER, "FREED %d block bytes\n", BlockSize ); // del me now !
|
|
psHeap->TotalAllocated-=BlockSize;
|
|
#endif
|
|
|
|
psCurr->pFree = psCurr->pLastAllocated;
|
|
psCurr->pLastAllocated=0; // remove pointer so that it cant be allocated again
|
|
|
|
|
|
return(TRUE); // able to return mem
|
|
}
|
|
}
|
|
return(FALSE); // unable to free mem
|
|
|
|
}
|
|
#endif
|
|
|
|
// Allocate some memory from a block heap
|
|
void *blkAlloc(BLOCK_HEAP *psHeap, SDWORD size)
|
|
{
|
|
void *pAlloc;
|
|
BLOCK_HEAP_MEM *psCurr, *psNew;
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
SDWORD allocSize;
|
|
MEM_NODE *psNode;
|
|
#endif
|
|
|
|
|
|
|
|
// Round up to nearest 4 bytes ( 32 bit align ).. Neaded for Playstation.. PD.
|
|
size = (size + 3) & 0xfffffffc;
|
|
|
|
|
|
// can't allocate 0 bytes
|
|
if (size <= 0)
|
|
{
|
|
ASSERT( FALSE, "blkAlloc: cannot allocate 0 bytes" );
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
// see if free has been called for this block
|
|
if (psHeap->free)
|
|
{
|
|
debug( LOG_NEVER, "Block Heap: %s at %d: Alloc after free:\n free %s at %d\n alloc %s at %d\n", psHeap->pFileName, psHeap->line, psHeap->pFreeFile, psHeap->freeLine, pCallFileName, callLine );
|
|
psHeap->free = FALSE;
|
|
}
|
|
|
|
// increase the size of the block to allow for the treap entry and overwrite blocks
|
|
allocSize = size;
|
|
size += sizeof(MEM_NODE) + 2 * SAFETY_ZONE_SIZE;
|
|
psHeap->TotalAllocated+=allocSize;
|
|
#endif
|
|
|
|
// find a block with a large enough segment free
|
|
pAlloc = NULL;
|
|
for(psCurr = psHeap->psBlocks; psCurr; psCurr = psCurr->psNext)
|
|
{
|
|
if (psCurr->pFree + size <= psCurr->pMem + psCurr->size)
|
|
{
|
|
pAlloc = psCurr->pFree;
|
|
|
|
psCurr->pFree += size;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if there wasn't a block try to allocate a new one
|
|
if ((psCurr == NULL) && (psHeap->ext != 0))
|
|
{
|
|
psNew = (BLOCK_HEAP_MEM*)RMALLOC(sizeof(BLOCK_HEAP_MEM));
|
|
if (!psNew)
|
|
{
|
|
ASSERT( FALSE, "blkAlloc: warning out of memory" );
|
|
|
|
// Out of memory
|
|
return NULL;
|
|
|
|
}
|
|
if (size < psHeap->ext)
|
|
{
|
|
psNew->pMem = (UBYTE*)RMALLOC(psHeap->ext);
|
|
psNew->size = psHeap->ext;
|
|
}
|
|
else
|
|
{
|
|
psNew->pMem = (UBYTE*)RMALLOC(size);
|
|
psNew->size = size;
|
|
}
|
|
if (!psNew->pMem)
|
|
{
|
|
// Out of memory
|
|
RFREE(psNew);
|
|
ASSERT( FALSE, "blkAlloc: warning out of memory" );
|
|
return NULL;
|
|
}
|
|
psNew->psNext = NULL;
|
|
|
|
psNew->pFree = psNew->pMem + size;
|
|
pAlloc = psNew->pMem;
|
|
|
|
// Add the block to the end of the list
|
|
for(psCurr=psHeap->psBlocks; psCurr->psNext != NULL; psCurr = psCurr->psNext)
|
|
;
|
|
psCurr->psNext = psNew;
|
|
}
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
if (!pAlloc)
|
|
{
|
|
// failed to allocate the memory
|
|
|
|
ASSERT( FALSE, "Warning: malloc returning NULL - [%s - %d] %d bytes",pCallFileName,callLine, size );
|
|
return NULL;
|
|
}
|
|
|
|
// add the allocated memory into the treap
|
|
psNode = (MEM_NODE *)pAlloc;
|
|
psNode->pFile = pCallFileName;
|
|
psNode->line = callLine;
|
|
psNode->size = allocSize;
|
|
|
|
/* Store the new entry in the memory treap */
|
|
psNode->priority = (UDWORD)rand();
|
|
psNode->key = (UDWORD)psNode;
|
|
psNode->pObj = psNode;
|
|
psNode->psLeft = NULL;
|
|
psNode->psRight = NULL;
|
|
treapAddNode((TREAP_NODE **)&psHeap->psMemTreap, (TREAP_NODE *)psNode, memBlockCmp);
|
|
|
|
/* Now initialise the memory - try to catch unitialised variables */
|
|
memset((UBYTE *)(psNode) + sizeof(MEM_NODE),
|
|
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
|
memset((UBYTE *)(psNode) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE + allocSize,
|
|
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
|
#if MEMORY_SET
|
|
/* The PC initialises malloc'ed memory already, no need to do it again */
|
|
memset((UBYTE *)(psNode) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE,
|
|
INITIALISE_BYTE, allocSize);
|
|
#endif
|
|
|
|
// offset the return value by the header size
|
|
pAlloc = ((UBYTE *)(pAlloc) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE);
|
|
#endif
|
|
|
|
psCurr->pLastAllocated=(UBYTE*)pAlloc;
|
|
///* - error trapping an out-of-mem allocation !!!
|
|
|
|
//NoMemChk:
|
|
return pAlloc;
|
|
}
|
|
//*/
|
|
|
|
// return a chunk of memory to the block
|
|
// this only does anything whith DEBUG_BLOCK defined
|
|
void blkFree(BLOCK_HEAP *psHeap, void *pMemToFree)
|
|
{
|
|
#ifdef DEBUG_BLOCK
|
|
MEM_NODE sNode, *psDeleted;
|
|
SDWORD i, InvalidBottom, InvalidTop;
|
|
UBYTE *pMemBase;
|
|
#if MEMORY_SET
|
|
SDWORD Size;
|
|
#endif
|
|
|
|
|
|
// note the call to free
|
|
psHeap->free = TRUE;
|
|
psHeap->pFreeFile = pCallFileName;
|
|
psHeap->freeLine = callLine;
|
|
|
|
// Create a dummy node for the search
|
|
// This is only looked at by memBlockCmp so only need to set the object and size
|
|
sNode.pObj = ((UBYTE *)pMemToFree) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
|
sNode.size = 1;
|
|
|
|
/* Get the node for the memory block */
|
|
psDeleted = (MEM_NODE *)treapDelRec((TREAP_NODE **)&psHeap->psMemTreap,
|
|
(UDWORD)&sNode, memBlockCmp);
|
|
ASSERT( psDeleted != NULL,
|
|
"Invalid pointer passed to mem_Free by:\n"
|
|
"File: %s\nLine: %d\n\n"
|
|
"Attempt to free already freed pointer?",
|
|
pCallFileName, callLine );
|
|
if (psDeleted)
|
|
{
|
|
/* The pointer is valid, check the buffer zones */
|
|
pMemBase = (UBYTE *)(pMemToFree) - SAFETY_ZONE_SIZE;
|
|
InvalidBottom = InvalidTop = 0;
|
|
for(i=0; i<SAFETY_ZONE_SIZE; i++)
|
|
{
|
|
if (pMemBase[i] != SAFETY_ZONE_BYTE)
|
|
{
|
|
InvalidBottom++;
|
|
}
|
|
if (pMemBase[i + psDeleted->size + SAFETY_ZONE_SIZE] != SAFETY_ZONE_BYTE)
|
|
{
|
|
InvalidTop++;
|
|
}
|
|
}
|
|
// this breaks debug... ***** look into why...
|
|
// ASSERT( !InvalidBottom && !InvalidTop,
|
|
// "Safety zone on memory overwritten.\n"
|
|
// "%d Invalid bytes (of %d) found below memory buffer.\n"
|
|
// "%d Invalid bytes (of %d) found above memory buffer.\n\n"
|
|
// "Memory allocated by:\nFile: %s\nLine: %d\n"
|
|
// "Memory freed by:\nFile: %s\nLine: %d\n",
|
|
// InvalidBottom, SAFETY_ZONE_SIZE, InvalidTop, SAFETY_ZONE_SIZE,
|
|
// psDeleted->pFile, psDeleted->line,
|
|
// pCallFileName, callLine );
|
|
|
|
/* Trash the memory before it is freed */
|
|
#if MEMORY_SET
|
|
Size = psDeleted->size;
|
|
memset(pMemToFree, FREE_BYTE, Size);
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
// non debug free !
|
|
// psHeap = psHeap;
|
|
// pMemToFree = pMemToFree;
|
|
#endif
|
|
|
|
{
|
|
// BOOL bRes;
|
|
|
|
#if(1)
|
|
|
|
//DBPRINTF(("UNABLE TO FREE MEMORY\n"));
|
|
|
|
|
|
#else
|
|
bRes=blkSpecialFree(psHeap, pMemToFree); // Free it up if we can ! - we can only free the last entry
|
|
#ifdef DEBUG
|
|
if (bRes==TRUE)
|
|
{
|
|
debug( LOG_NEVER, "blkFree called - memory successfully released\n" );
|
|
}
|
|
else
|
|
{
|
|
// debug( LOG_NEVER, "blkFree called - memory NOT released\n" );
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset a block heap
|
|
void blkReset(BLOCK_HEAP *psHeap)
|
|
{
|
|
BLOCK_HEAP_MEM *psCurr;
|
|
#ifdef DEBUG_GROUP0
|
|
SDWORD block=0, alloc=0;
|
|
#endif
|
|
|
|
#ifdef DEBUG_BLOCK
|
|
if (psHeap->psMemTreap != NULL)
|
|
{
|
|
debug( LOG_NEVER, "blkReset: %s at %d: memory allocated :\n", psHeap->pFileName, psHeap->line );
|
|
memRecReport(psHeap->psMemTreap);
|
|
}
|
|
psHeap->psMemTreap = NULL;
|
|
psHeap->free = FALSE;
|
|
|
|
psHeap->TotalAllocated=0;
|
|
|
|
debug( LOG_NEVER, "blkReset: %s at %d: memory usage:\n", psHeap->pFileName, psHeap->line );
|
|
#else
|
|
debug( LOG_NEVER, "blkReset: memory usage:\n" );
|
|
#endif
|
|
|
|
psCurr = psHeap->psBlocks;
|
|
while(psCurr)
|
|
{
|
|
#ifdef DEBUG_GROUP0
|
|
alloc += psCurr->pFree - psCurr->pMem;
|
|
block += psCurr->size;
|
|
#endif
|
|
#if defined(DEBUG_BLOCK) && MEMORY_SET
|
|
memset(psCurr->pMem, FREE_BYTE, psCurr->size);
|
|
#endif
|
|
psCurr->pFree = psCurr->pMem;
|
|
psCurr = psCurr->psNext;
|
|
}
|
|
|
|
debug( LOG_NEVER, " Blocks allocated %dk, Memory allocated %dk\n", block/1024, alloc/1024 );
|
|
}
|
|
|
|
|
|
// Find which block a pointer is from if any
|
|
BLOCK_HEAP *blkFind(void *pPtr)
|
|
{
|
|
BLOCK_HEAP *psHeap;
|
|
BLOCK_HEAP_MEM *psMem;
|
|
|
|
for(psHeap=psBlockList; psHeap; psHeap=psHeap->psNext)
|
|
{
|
|
for(psMem=psHeap->psBlocks; psMem; psMem=psMem->psNext)
|
|
{
|
|
if ((UBYTE *)pPtr >= psMem->pMem &&
|
|
(UBYTE *)pPtr < psMem->pMem + psMem->size)
|
|
{
|
|
return psHeap;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// check if a pointer is valid in a block
|
|
BOOL blkPointerValid(BLOCK_HEAP *psHeap, void *pData, SDWORD size)
|
|
{
|
|
#ifdef DEBUG_BLOCK
|
|
MEM_NODE sNode;
|
|
void *Tmp;
|
|
|
|
ASSERT( size, "blkPointerValid: cannot check a pointer with zero size" );
|
|
|
|
if (pData == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Create a dummy node for the search
|
|
// This is only looked at by memBlockCmp so only need to set the object and size
|
|
sNode.pObj = ((UBYTE *)pData) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
|
sNode.size = size;
|
|
|
|
// See if the block is in the treap
|
|
Tmp = treapFindRec((TREAP_NODE *)psHeap->psMemTreap, (UDWORD)&sNode, memBlockCmp);
|
|
if (Tmp != NULL)
|
|
// if (treapFindRec((TREAP_NODE *)psHeap->psMemTreap, (UDWORD)&sNode, memBlockCmp))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
#else
|
|
psHeap = psHeap;
|
|
pData = pData;
|
|
size = size;
|
|
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
// check if a pointer is valid in any currently allocated block
|
|
BOOL blkPointerValidAll(void *pData, SDWORD size)
|
|
{
|
|
#ifdef DEBUG_BLOCK
|
|
BLOCK_HEAP *psCurr;
|
|
|
|
for(psCurr=psBlockList; psCurr; psCurr=psCurr->psNext)
|
|
{
|
|
if (blkPointerValid(psCurr, pData, size))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
#else
|
|
pData = pData;
|
|
size = size;
|
|
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
BLOCK_HEAP *psSuspendedHeap=NULL;
|
|
|
|
// suspend the current block ... all allocations pass though to system memory allocation
|
|
// if a block is already suspended then an assertion will occur.
|
|
void blockSuspendUsage(void)
|
|
{
|
|
ASSERT( psSuspendedHeap==NULL, "a memory block is already suspended" );
|
|
|
|
psSuspendedHeap = memGetBlockHeap();
|
|
memSetBlockHeap(NULL);
|
|
|
|
}
|
|
|
|
// restore the current block - if there is one
|
|
void blockUnsuspendUsage(void)
|
|
{
|
|
memSetBlockHeap(psSuspendedHeap);
|
|
psSuspendedHeap=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void blockCurrentBlockInfo(void)
|
|
{
|
|
#ifdef DEBUG
|
|
BLOCK_HEAP *psCurHeap;
|
|
|
|
psCurHeap=memGetBlockHeap();
|
|
if (psCurHeap==NULL)
|
|
{
|
|
debug( LOG_NEVER, "*** No current block defined\n" );
|
|
}
|
|
else
|
|
{
|
|
UDWORD Left=(UDWORD)((psCurHeap->psBlocks->pMem)+(psCurHeap->psBlocks->size)-(psCurHeap->psBlocks->pFree));
|
|
|
|
debug( LOG_NEVER, "ptr=%p init=%d ext=%d used=%d (Start=$%p Free=$%p Left=%d)\n", psCurHeap, psCurHeap->init, psCurHeap->ext, psCurHeap->TotalAllocated, psCurHeap->psBlocks->pMem, psCurHeap->psBlocks->pFree, Left );
|
|
}
|
|
#endif
|
|
}
|