NLMEMORY::CHeapAllocator Class Reference

#include <heap_allocator.h>


Small Block

enum  {
  SmallBlockGranularityShift = 3, SmallBlockGranularity = 1<<SmallBlockGranularityShift, FirstSmallBlock = 8, LastSmallBlock = 128,
  SmallBlockPoolSize = 20
}
bool checkNodeSB (const CSmallBlockPool *mainBlock, const CNodeBegin *previous, const CNodeBegin *current, const CNodeBegin *next, bool stopOnError) const
uint8internalAllocateBlock (uint size)
void outOfMemory ()
volatile CNodeBegin_FreeSmallBlocks [(1+(LastSmallBlock-FirstSmallBlock)/SmallBlockGranularity)]
CMemoryMutex _MutexSB
volatile CSmallBlockPool_SmallBlockPool
CNodeBegingetNextSmallBlock (CNodeBegin *previous)
CNodeBegingetSmallBlock (CSmallBlockPool *smallBlock, uint blockIndex)
void setNextSmallBlock (CNodeBegin *previous, CNodeBegin *next)

Interface

enum  TBlockAllocationMode { Grow, DontGrow }
enum  TOutOfMemoryMode { ThrowException, ReturnNull }
 CHeapAllocator (uint mainBlockSize=1024 *1024 *10, uint blockCount=1, TBlockAllocationMode blockAllocationMode=Grow, TOutOfMemoryMode outOfMemoryMode=ThrowException)
void free (void *ptr)
void freeAll ()
void releaseMemory ()
virtual ~CHeapAllocator ()
uint getBlockSize (void *block)
const char * getCategory (void *block)

Implementation

void * allocate (uint size, const char *sourceFile, uint line, const char *category)
void * reallocate (void *ptr, uint size, const char *sourceFile, uint line, const char *category)
enum  {
  ReleaseHeaderSize = 8, CategoryStringLength = 8, BeginNodeMarkers = '<', EndNodeMarkers = '>',
  UnallocatedMemory = 0xba, UninitializedMemory = 0xbc, DeletedMemory = 0xbd, NameLength = 32
}
enum  { FreeNodeBlockSize = 128, FreeNodeBlockSizeShift = 7, FreeNodeBlockSizeMask = 0x7f }
enum  { Align = 8, BlockDataSizeMin = 1<<4 }
enum  { UserDataBlockSizeMin = sizeof(CFreeNode) }
typedef char TCategoryString [CategoryStringLength]
bool checkFreeNode (const CFreeNode *current, bool stopOnError, bool recurse) const
void checkNode (const CNodeBegin *current, uint32 crc) const
bool checkNodeLB (const CMainBlock *mainBlock, const CNodeBegin *previous, const CNodeBegin *current, const CNodeBegin *next, bool stopOnError) const
void enterCriticalSection () const
void enterCriticalSectionLB () const
void enterCriticalSectionSB () const
void erase (CFreeNode *z)
CFreeNodefind (uint size)
void initEmptyBlock (CMainBlock &mainBlock)
void insert (CFreeNode *x)
bool internalCheckHeap (bool stopOnError) const
void leaveCriticalSection () const
void leaveCriticalSectionLB () const
void leaveCriticalSectionSB () const
void rotateLeft (CFreeNode *x)
void rotateRight (CFreeNode *x)
CNodeBeginsplitNode (CNodeBegin *node, uint newSize)
uint32 _AllocateCount
bool _AlwaysCheck
TBlockAllocationMode _BlockAllocationMode
uint _BlockCount
CFreeNode_FreeTreeRoot
CMainBlock_MainBlockList
uint _MainBlockSize
CMemoryMutex _MutexLB
char _Name [NameLength]
CNullNode _NullNode
TOutOfMemoryMode _OutOfMemoryMode
void computeCRC32 (uint32 &crc, const void *buffer, unsigned int count)
uint32 evalMagicNumber (const CNodeBegin *node)
CNodeBegingetFirstNode (CMainBlock *mainBlock)
const CNodeBegingetFirstNode (const CMainBlock *mainBlock)
CFreeNodegetFreeNode (CNodeBegin *current)
const CFreeNodegetFreeNode (const CNodeBegin *current)
CNodeBegingetNextNode (CNodeBegin *current)
const CNodeBegingetNextNode (const CNodeBegin *current)
CNodeBegingetNode (CFreeNode *current)
const CNodeBegingetNode (const CFreeNode *current)
uint getNodeSize (const CNodeBegin *current)
bool isNodeBlack (const CFreeNode *current)
bool isNodeFree (const CNodeBegin *current)
bool isNodeLast (const CNodeBegin *current)
bool isNodeRed (const CFreeNode *current)
bool isNodeSmall (const CNodeBegin *current)
bool isNodeUsed (const CNodeBegin *current)
void mergeNode (CNodeBegin *node)
void setNodeBlack (CFreeNode *current)
void setNodeColor (CFreeNode *current, bool red)
void setNodeFree (CNodeBegin *current)
void setNodeLast (CNodeBegin *current, bool last)
void setNodeRed (CFreeNode *current)
void setNodeSize (CNodeBegin *current, uint size)
void setNodeUsed (CNodeBegin *current)
struct CNodeBegin

Performance control

bool checkHeap (bool stopOnError) const
void debugAlwaysCheckMemory (bool alwaysCheck)
uint debugGetAllocatedMemoryByCategory (const char *category) const
uint debugGetDebugInfoSize () const
uint debugGetLBDebugInfoSize () const
uint debugGetSBDebugInfoSize () const
bool debugIsAlwaysCheckMemory () const
void debugReportMemoryLeak ()
bool debugStatisticsReport (const char *stateFile, bool memoryMap)
uint getAllocatedMemory () const
uint getAllocatedSystemMemoryByAllocator ()
TBlockAllocationMode getBlockAllocationMode () const
float getFragmentationRatio () const
uint getFreeMemory () const
uint getMainBlockCount () const
uint getMainBlockSize () const
const char * getName () const
TOutOfMemoryMode getOutOfMemoryMode () const
uint getSmallBlockMemory () const
uint getTotalMemoryUsed () const
void setBlockAllocationMode (TBlockAllocationMode mode)
bool setMainBlockCount (uint blockCount)
bool setMainBlockSize (uint mainBlockSize)
void setName (const char *name)
void setOutOfMemoryHook (void(*outOfMemoryCallback)())
void setOutOfMemoryMode (TOutOfMemoryMode mode)
uint getAllocatedSystemMemory ()

Category control

void debugPopCategoryString ()
void debugPushCategoryString (const char *str)
CMemoryTDS _CategoryStack
void(* _OutOfMemoryCallback )()

Public Types


Public Member Functions

Overridable
virtual uint8allocateBlock (uint size)
virtual void freeBlock (uint8 *block)

Private Types


Member Typedef Documentation

typedef char NLMEMORY::CHeapAllocator::TCategoryString[CategoryStringLength] [private]
 

Definition at line 220 of file src/memory/heap_allocator.h.


Member Enumeration Documentation

anonymous enum [private]
 

Enumeration values:
ReleaseHeaderSize 
CategoryStringLength 
BeginNodeMarkers 
EndNodeMarkers 
UnallocatedMemory 
UninitializedMemory 
DeletedMemory 
NameLength 

Definition at line 208 of file src/memory/heap_allocator.h.

00209         { 
00210                 ReleaseHeaderSize               =       8,
00211                 CategoryStringLength    =       8,
00212                 BeginNodeMarkers                =       '<',
00213                 EndNodeMarkers                  =       '>',
00214                 UnallocatedMemory               =       0xba,
00215                 UninitializedMemory             =       0xbc,
00216                 DeletedMemory                   =       0xbd,
00217                 NameLength                              =       32
00218         };

anonymous enum [private]
 

Enumeration values:
FreeNodeBlockSize 
FreeNodeBlockSizeShift 
FreeNodeBlockSizeMask 

Definition at line 253 of file src/memory/heap_allocator.h.

00254         { 
00255                 FreeNodeBlockSize = 128, 
00256                 FreeNodeBlockSizeShift = 7, 
00257                 FreeNodeBlockSizeMask = 0x7f 
00258         };

anonymous enum [private]
 

Enumeration values:
Align 
BlockDataSizeMin 

Definition at line 261 of file src/memory/heap_allocator.h.

00262         { 
00263                 Align = 8,
00264                 BlockDataSizeMin = 1<<4
00265         };

anonymous enum [private]
 

Enumeration values:
UserDataBlockSizeMin 

Definition at line 379 of file src/memory/heap_allocator.h.

00380         {
00381                 UserDataBlockSizeMin = sizeof(CFreeNode)
00382         };

anonymous enum
 

Enumeration values:
SmallBlockGranularityShift 
SmallBlockGranularity 
FirstSmallBlock 
LastSmallBlock 
SmallBlockPoolSize 

Definition at line 451 of file src/memory/heap_allocator.h.

00452         {
00453                 // Small block granularity
00454                 SmallBlockGranularityShift = 3,
00455 
00456                 // Small block granularity
00457                 SmallBlockGranularity = 1<<SmallBlockGranularityShift,
00458 
00459                 // Smallest block size
00460                 FirstSmallBlock = 8,
00461 
00462                 // Largest block size
00463                 LastSmallBlock = 128,
00464 
00465                 // Size of a smallblock pool
00466                 SmallBlockPoolSize = 20
00467         };

enum NLMEMORY::CHeapAllocator::TBlockAllocationMode
 

Block allocation mode.

Enumeration values:
Grow  When the allocator runs out of memory, allocate a new block.
DontGrow  When the allocator runs out of memory, returns a out of memory signal.

Definition at line 72 of file src/memory/heap_allocator.h.

00073         { 
00075                 Grow, 
00076 
00078                 DontGrow 
00079         };

enum NLMEMORY::CHeapAllocator::TOutOfMemoryMode
 

Out of memory signal

Enumeration values:
ThrowException  When the allocator runs out of memory, throw an exception.
ReturnNull  When the allocator runs out of memory, returns NULL.

Definition at line 84 of file src/memory/heap_allocator.h.

00085         { 
00087                 ThrowException, 
00088 
00090                 ReturnNull 
00091         };


Constructor & Destructor Documentation

NLMEMORY::CHeapAllocator::CHeapAllocator uint  mainBlockSize = 1024 *1024 *10,
uint  blockCount = 1,
TBlockAllocationMode  blockAllocationMode = Grow,
TOutOfMemoryMode  outOfMemoryMode = ThrowException
 

Constructor / Destructor

Definition at line 936 of file memory/heap_allocator.cpp.

References NLMEMORY::line, uint32, and uint8.

00961                                 {
00962                                         // Fill informations for the second part of the node
00963 
00964                                         // Get the freeNode
00965                                         freeNode = getFreeNode (rest);
00966 
00967                                         // Insert the free node
00968                                         insert (freeNode);
00969 
00970                                         // Crc node
00971                                         NL_UPDATE_MAGIC_NUMBER (rest);
00972                                 }
00973 
00974                                 // Check the node size
00975                                 internalAssert ( size <= getNodeSize (node) );
00976                                 internalAssert ( std::max ((uint)BlockDataSizeMin, size + (uint)Align) + sizeof (CNodeBegin) + sizeof (CNodeEnd) + sizeof (CNodeBegin) + sizeof (CNodeEnd) + BlockDataSizeMin >= getNodeSize (node) );
00977 
00978                                 // Check pointer alignment
00979                                 internalAssert (((uint32)node&(Align-1)) == 0);
00980                                 internalAssert (((uint32)((char*)node + sizeof(CNodeBegin))&(Align-1)) == 0);
00981 
00982                                 // Check size
00983                                 internalAssert ((uint32)node->EndMagicNumber <= (uint32)((uint8*)node+sizeof(CNodeBegin)+getNodeSize (node) ));
00984                                 internalAssert ((uint32)node->EndMagicNumber > (uint32)(((uint8*)node+sizeof(CNodeBegin)+getNodeSize (node) ) - BlockDataSizeMin - BlockDataSizeMin - sizeof(CNodeBegin) - sizeof(CNodeEnd)));
00985 
00986                                 leaveCriticalSectionLB ();
00987 
00988                                 // Return the user pointer
00989                                 return (void*)((uint)node + sizeof (CNodeBegin));
00990                         }
00991                         else
00992                         {
00993                                 // ********

NLMEMORY::CHeapAllocator::~CHeapAllocator  )  [virtual]
 

Destruction

Definition at line 997 of file memory/heap_allocator.cpp.

References NL_ALLOC_STOP.

01006         {


Member Function Documentation

void * NLMEMORY::CHeapAllocator::allocate uint  size,
const char *  sourceFile,
uint  line,
const char *  category
 

Definition at line 1527 of file memory/heap_allocator.cpp.

Referenced by NLMEMORY::__declspec().

01528                                         {
01529                                                 catMap = CCategoryMap::insert (current->Category, catMap);
01530                                                 cat = catMap;
01531                                         }
01532                                         uint size = getNodeSize (current) + ReleaseHeaderSize;
01533                                         cat->BlockCount++;
01534                                         cat->Size += size;
01535                                         if (size < cat->Min)
01536                                                 cat->Min = size;
01537                                         if (size > cat->Max)
01538                                                 cat->Max = size;
01539                                 }
01540 
01541                                 // Next node
01542                                 current = getNextNode (current);
01543                                 largeBlockCount++;
01544                         }
01545 
01546                         // Next block
01547                         currentBlock = currentBlock->Next;
01548                 }
01549 
01550                 // Write the heap info file
01551                 fprintf (file, "HEAP STATISTICS\n");
01552                 fprintf (file, "HEAP, TOTAL MEMORY USED, ALLOCATED MEMORY, FREE MEMORY, FRAGMENTATION RATIO, MAIN BLOCK SIZE, MAIN BLOCK COUNT\n");
01553 
01554                 fprintf (file, "%s, %d, %d, %d, %f%%, %d, %d\n", _Name, getTotalMemoryUsed (),
01555                         getAllocatedMemory (), getFreeMemory (), 100.f*getFragmentationRatio (), getMainBlockSize (), getMainBlockCount ());
01556 
01557                 fprintf (file, "\n\nHEAP BLOCKS\n");
01558                 fprintf (file, "SMALL BLOCK MEMORY, SMALL BLOCK COUNT, LARGE BLOCK COUNT\n");
01559 
01560                 fprintf (file, "%d, %d, %d\n", getSmallBlockMemory (), smallBlockCount, largeBlockCount);
01561 
01562                 fprintf (file, "\n\nHEAP DEBUG INFOS\n");
01563                 fprintf (file, "SB DEBUG INFO, LB DEBUG INFO, TOTAL DEBUG INFO\n");
01564 
01565                 fprintf (file, "%d, %d, %d\n", debugGetSBDebugInfoSize (), debugGetLBDebugInfoSize (), debugGetDebugInfoSize ());
01566 
01567                 // **************************
01568 
01569                 // Write the system heap info file
01570                 uint systemMemory = getAllocatedSystemMemory ();
01571                 uint hookedSystemMemory = GetAllocatedSystemMemoryHook ();
01572                 uint nelSystemMemory = getAllocatedSystemMemoryByAllocator ();
01573 
01574                 fprintf (file, "\n\nSYSTEM HEAP STATISTICS\n");
01575                 fprintf (file, "SYSTEM HEAP ALLOCATED MEMORY, TOTAL HOOKED MEMORY, NEL ALLOCATED MEMORY, OTHER ALLOCATED MEMORY, NOT HOOKED MEMORY\n");
01576                 fprintf (file, "%d, %d, %d, %d, %d\n", systemMemory, hookedSystemMemory, nelSystemMemory, hookedSystemMemory-nelSystemMemory, systemMemory-hookedSystemMemory);
01577                 
01578                 // **************************
01579                 
01580                 // Write the category map file
01581                 fprintf (file, "\n\n\nCATEGORY STATISTICS\n");
01582                 fprintf (file, "CATEGORY, BLOCK COUNT, MEMORY ALLOCATED, MIN BLOCK SIZE, MAX BLOCK SIZE, AVERAGE BLOCK SIZE, SB COUNT 8, SB COUNT 16, SB COUNT 24, SB COUNT 32, SB COUNT 40, SB COUNT 48, SB COUNT 56, SB COUNT 64, SB COUNT 72, SB COUNT 80, SB COUNT 88, SB COUNT 96, SB COUNT 104, SB COUNT 112, SB COUNT 120, SB COUNT 128\n");
01583 
01584                 CCategoryMap *cat = catMap;
01585                 while (cat)
01586                 {
01587                         CCategoryMap *next = cat->Next;
01588 
01589                         // Number of small blocks
01590                         uint smallB[NL_SMALLBLOCK_COUNT];
01591 
01592                         // Clean
01593                         uint smallBlock;
01594                         for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
01595                         {
01596                                 smallB[smallBlock] = 0;
01597                         }
01598                         
01599                         // Scan small block for this category
01600                         currentSB = (CSmallBlockPool *)_SmallBlockPool;
01601                         while (currentSB)
01602                         {
01603                                 // For each node in this small block pool
01604                                 uint block;
01605                                 for (block=0; block<SmallBlockPoolSize; block++)
01606                                 {
01607                                         // Get the node
01608                                         const CNodeBegin *current = getSmallBlock (currentSB, block);
01609 
01610                                         // Node allocated ?
01611                                         if (isNodeUsed (current))
01612                                         {
01613                                                 // Good node ?
01614                                                 if (strcmp (current->Category, cat->Name) == 0)
01615                                                 {
01616                                                         // Get the small block index
01617                                                         uint index = NL_SIZE_TO_SMALLBLOCK_INDEX (getNodeSize (current));
01618 
01619                                                         // One more node
01620                                                         smallB[index]++;
01621                                                 }
01622                                         }
01623                                 }
01624 
01625                                 // Next block
01626                                 currentSB = currentSB->Next;
01627                         }
01628 
01629                         // Average
01630                         uint average = cat->Size / cat->BlockCount;
01631 
01632                         // Print the line
01633                         fprintf (file, "%s, %d, %d, %d, %d, %d", cat->Name, cat->BlockCount, cat->Size, 
01634                                 cat->Min, cat->Max, average);
01635 
01636                         // Print small blocks
01637                         for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
01638                         {
01639                                 fprintf (file, ", %d", smallB[smallBlock]);
01640                         }
01641 
01642                         fprintf (file, "\n");
01643 
01644                         delete cat;
01645                         cat = next;
01646                 }
01647 
01648                 // **************************
01649 
01650                 // Write the small block statistics
01651                 fprintf (file, "\n\n\nSMALL BLOCK STATISTICS\n");
01652                 fprintf (file, "SIZE, BLOCK COUNT, BLOCK FREE, BLOCK USED, TOTAL MEMORY USED\n");
01653 
01654                 // Number of small blocks
01655                 uint count[NL_SMALLBLOCK_COUNT];
01656                 uint free[NL_SMALLBLOCK_COUNT];
01657 
01658                 uint smallBlock;
01659                 for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
01660                 {
01661                         count[smallBlock] = 0;
01662                         free[smallBlock] = 0;
01663                 }
01664 
01665                 // For each small block
01666                 currentSB = (CSmallBlockPool *)_SmallBlockPool;
01667                 while (currentSB)
01668                 {
01669                         // For each node in this small block pool
01670                         uint block;
01671                         for (block=0; block<SmallBlockPoolSize; block++)
01672                         {
01673                                 // Get the node
01674                                 const CNodeBegin *current = getSmallBlock (currentSB, block);
01675 
01676                                 // Get the small block index
01677                                 uint index = NL_SIZE_TO_SMALLBLOCK_INDEX (getNodeSize (current));
01678 
01679                                 // Add a block
01680                                 count[index]++;
01681 
01682                                 // Node allocated ?
01683                                 if (isNodeFree (current))
01684                                 {
01685                                         // Add a free block
01686                                         free[index]++;
01687                                 }
01688 
01689                                 // Next node
01690                                 current = getNextNode (current);
01691                         }
01692 
01693                         // Next block
01694                         currentSB = currentSB->Next;
01695                 }
01696 
01697                 // Print stats
01698                 for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
01699                 {
01700                         uint size = (smallBlock+1)*SmallBlockGranularity;
01701                         fprintf (file,"%d, %d, %d, %d, %d\n",size, count[smallBlock], free[smallBlock], 
01702                                 count[smallBlock]-free[smallBlock], count[smallBlock]*(sizeof (CNodeBegin) + size + NL_HEAP_NODE_END_SIZE));
01703                 }
01704                 
01705                 // **************************
01706 
01707                 // Write the memory map file
01708                 if (memoryMap)
01709                 {
01710                         fprintf (file, "\n\n\nHEAP LARGE BLOCK DUMP\n");
01711                         fprintf (file, "ADDRESS, SIZE, CATEGORY, HEAP, STATE, SOURCE, LINE\n");
01712 
01713                         // For each main block
01714                         currentBlock = _MainBlockList;
01715                         while (currentBlock)
01716                         {
01717                                 // Get the first node
01718                                 const CNodeBegin *current = getFirstNode (currentBlock);
01719                                 while (current)
01720                                 {
01721                                         // Write the entry
01722                                         fprintf (file, "0x%08x, %d, %s, %s, %s, %s, %d\n", (uint)current + sizeof(CNodeBegin),
01723                                                 getNodeSize (current), current->Category, _Name, 
01724                                                 isNodeFree (current)?"free":"used", current->File, current->Line);
01725 
01726                                         // Next node
01727                                         current = getNextNode (current);
01728                                 }
01729 
01730                                 // Next block
01731                                 currentBlock = currentBlock->Next;
01732                         }
01733                 }
01734 
01735                 // File created successfuly
01736                 status = true;
01737         }
01738 
01739         // Close
01740         if (file)
01741                 fclose (file);
01742 
01743         debugPopCategoryString ();
01744 
01745         return status;
01746 }
01747 #endif // NL_HEAP_ALLOCATION_NDEBUG
01748 
01749 // *********************************************************
01750 
01751 uint CHeapAllocator::getFreeMemory () const
01752 {
01753         enterCriticalSection ();
01754 
01755         // Sum free memory
01756         uint memory = 0;
01757 
01758         // For each small block
01759         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
01760         while (currentSB)
01761         {
01762                 // For each node in this small block pool
01763                 uint block;
01764                 for (block=0; block<SmallBlockPoolSize; block++)
01765                 {
01766                         // Get the node
01767                         const CNodeBegin *current = getSmallBlock (currentSB, block);
01768 
01769                         // Node allocated ?
01770                         if (isNodeFree (current))
01771                                 memory  += getNodeSize (current) + ReleaseHeaderSize;
01772 
01773                         // Next node
01774                         current = getNextNode (current);
01775                 }
01776 
01777                 // Next block
01778                 currentSB = currentSB->Next;
01779         }
01780 
01781         // For each main block
01782         CMainBlock *currentBlock = _MainBlockList;
01783         while (currentBlock)
01784         {
01785                 // Get the first node
01786                 const CNodeBegin *current = getFirstNode (currentBlock);
01787                 while (current)
01788                 {
01789 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01790                         // Check node
01791                         checkNode (current, evalMagicNumber (current));
01792 #endif // NL_HEAP_ALLOCATION_NDEBUG
01793 
01794                         // Node allocated ?
01795                         if (isNodeFree (current))
01796                                 memory  += getNodeSize (current) + ReleaseHeaderSize;
01797 
01798                         // Next node
01799                         current = getNextNode (current);
01800                 }
01801 
01802                 // Next block
01803                 currentBlock = currentBlock->Next;
01804         }
01805 
01806         leaveCriticalSection ();
01807 
01808         // Return memory used
01809         return memory;
01810 }
01811 
01812 // *********************************************************
01813 
01814 uint CHeapAllocator::getTotalMemoryUsed () const
01815 {
01816         enterCriticalSection ();
01817 
01818         // Sum total memory
01819         uint memory = 0;
01820 
01821         // For each main block
01822         CMainBlock *currentBlock = _MainBlockList;
01823         while (currentBlock)
01824         {
01825                 // Get block size
01826                 memory += currentBlock->Size;
01827 
01828                 // Sum the arrays
01829                 memory += sizeof (CMainBlock);
01830 
01831                 // Next block
01832                 currentBlock = currentBlock->Next;
01833         }
01834 
01835         leaveCriticalSection ();
01836 
01837         // Return the memory
01838         return memory;
01839 }
01840 
01841 // *********************************************************
01842 
01843 uint CHeapAllocator::getSmallBlockMemory () const
01844 {
01845         enterCriticalSection ();
01846 
01847         // Sum total memory
01848         uint memory = 0;
01849 
01850         // For each small block
01851         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
01852         while (currentSB)
01853         {
01854                 // Get block size
01855                 memory += sizeof(CSmallBlockPool) + SmallBlockPoolSize * (sizeof(CNodeBegin) + currentSB->Size + 
01856                                         NL_HEAP_NODE_END_SIZE);
01857 
01858                 // Next block
01859                 currentSB = currentSB->Next;
01860         }
01861 
01862         leaveCriticalSection ();
01863 
01864         // Return the memory
01865         return memory;
01866 }
01867 
01868 // *********************************************************
01869 
01870 float CHeapAllocator::getFragmentationRatio () const
01871 {
01872         enterCriticalSection ();
01873 
01874         // Sum free and used node
01875         float free = 0;
01876         float used = 0;
01877 
01878         // For each main block
01879         CMainBlock *currentBlock = _MainBlockList;
01880         while (currentBlock)
01881         {
01882                 // Get the first node
01883                 const CNodeBegin *current = getFirstNode (currentBlock);
01884                 while (current)
01885                 {
01886                         // Node allocated ?
01887                         if (isNodeUsed (current))
01888                                 used++;
01889                         else
01890                                 free++;
01891 
01892                         // Next node

uint8 * NLMEMORY::CHeapAllocator::allocateBlock uint  size  )  [virtual]
 

Method used to allocate system memory

Definition at line 3038 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::checkFreeNode const CFreeNode current,
bool  stopOnError,
bool  recurse
const [inline, private]
 

Definition at line 640 of file memory/heap_allocator.cpp.

00652 {
00653         // Check size is valid
00654         if (size != 0)
00655         {
00656 #ifndef NL_HEAP_ALLOCATION_NDEBUG
00657                 // If category is NULL
00658                 if (category == NULL)
00659                 {
00660                         // Get the current category
00661                         CCategory *cat = (CCategory*)_CategoryStack.getPointer ();
00662                         if (cat)
00663                         {
00664                                 category = cat->Name;
00665                         }
00666                         else
00667                         {
00668                                 // Not yet initialised
00669                                 category = NL_HEAP_UNKNOWN_CATEGORY;
00670                         }
00671                 }
00672 
00673                 /* trap debug if (strcmp(category,"3dIns") == 0)
00674                 {
00675                         n3dDrvTotal += size;
00676                         uint dbg= 0;
00677                         dbg++;
00678                 }
00679                 */
00680 
00681                 // Checks ?
00682                 if (_AlwaysCheck)
00683                 {
00684                         // Check heap integrity
00685                         internalCheckHeap (true);
00686                 }
00687 
00688                 // Check breakpoints
00689                 /*if (_Breakpoints.find (_AllocateCount) != _Breakpoints.end())
00690                 {
00691                         // ********
00692                         // * STOP *
00693                         // ********
00694                         // * Breakpoints allocation
00695                         // ********
00696                         NL_ALLOC_STOP;
00697                 }*/
00698 #endif // NL_HEAP_ALLOCATION_NDEBUG
00699 
00700                 // Small or largs block ?
00701 #ifdef NL_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
00702                 if (0)
00703 #else // NL_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
00704                 if (size <= LastSmallBlock)
00705 #endif// NL_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
00706                 {
00707                         // *******************
00708                         // Small block
00709                         // *******************
00710                         
00711                         enterCriticalSectionSB ();
00712 
00713                         // Get pointer on the free block list
00714                         CNodeBegin **freeNode = (CNodeBegin **)_FreeSmallBlocks+NL_SIZE_TO_SMALLBLOCK_INDEX (size);
00715 
00716                         // Not found ?
00717                         if (*freeNode == NULL)
00718                         {
00719                                 leaveCriticalSectionSB ();
00720 
00721                                 // Size must be aligned
00722                                 uint alignedSize = NL_ALIGN_SIZE_FOR_SMALLBLOCK (size);
00723 
00724                                 // Use internal allocator
00725                                 CSmallBlockPool *smallBlock = (CSmallBlockPool *)NelAlloc (*this, sizeof(CSmallBlockPool) + SmallBlockPoolSize * (sizeof(CNodeBegin) + alignedSize + 
00726                                         NL_HEAP_NODE_END_SIZE), NL_HEAP_SB_CATEGORY);
00727 
00728                                 enterCriticalSectionSB ();
00729 
00730                                 // Link this new block
00731                                 smallBlock->Size = alignedSize;
00732                                 smallBlock->Next = (CSmallBlockPool*)_SmallBlockPool;
00733                                 _SmallBlockPool = smallBlock;
00734 
00735                                 // Initialize the block
00736                                 uint pool;
00737                                 CNodeBegin *nextNode = *freeNode;

bool NLMEMORY::CHeapAllocator::checkHeap bool  stopOnError  )  const
 

Definition at line 3029 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::checkNode const CNodeBegin current,
uint32  crc
const [private]
 

Definition at line 3193 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::checkNodeLB const CMainBlock mainBlock,
const CNodeBegin previous,
const CNodeBegin current,
const CNodeBegin next,
bool  stopOnError
const [inline, private]
 

Definition at line 540 of file memory/heap_allocator.cpp.

00568 {
00569         // Get the node pointer
00570         CNodeBegin *node = getFirstNode (&mainBlock);
00571 
00572         // Allocated size remaining after alignment
00573         internalAssert ((uint32)node - (uint32)mainBlock.Ptr >= 0);
00574         uint allocSize = mainBlock.Size - ((uint32)node - (uint32)mainBlock.Ptr);
00575 
00576         // *** Fill the new node header
00577 
00578         // User data size
00579         setNodeSize (node, allocSize-sizeof (CNodeBegin)-NL_HEAP_NODE_END_SIZE);
00580 
00581         // Node is free
00582         setNodeFree (node);
00583 
00584         // Node is last
00585         setNodeLast (node, true);
00586 
00587         // No previous node
00588         node->Previous = NULL;
00589 
00590         // Debug info
00591 #ifndef NL_HEAP_ALLOCATION_NDEBUG
00592         // End magic number
00593         node->EndMagicNumber = (uint32*)((uint8*)node + getNodeSize (node) + sizeof (CNodeBegin));
00594 
00595         // Begin markers
00596         memset (node->BeginMarkers, BeginNodeMarkers, CNodeBegin::MarkerSize-1);
00597         node->BeginMarkers[CNodeBegin::MarkerSize-1] = 0;
00598 
00599         // End markers
00600         CNodeEnd *endNode = (CNodeEnd*)node->EndMagicNumber;
00601         memset (endNode->EndMarkers, EndNodeMarkers, CNodeEnd::MarkerSize-1);
00602         endNode->EndMarkers[CNodeEnd::MarkerSize-1] = 0;
00603 
00604         // Unallocated memory
00605         memset ((uint8*)node + sizeof(CNodeBegin), UnallocatedMemory, getNodeSize (node) );
00606 
00607         // No source file
00608         memset (node->Category, 0, CategoryStringLength);
00609         node->File = NULL;
00610         node->Line = 0xffff;
00611         node->AllocateNumber = 0xffffffff;
00612 
00613         // Heap pointer
00614         node->Heap = this;
00615 
00616         NL_UPDATE_MAGIC_NUMBER (node);
00617 #endif // NL_HEAP_ALLOCATION_NDEBUG
00618 }
00619 
00620 // *********************************************************
00621 
00622 uint CHeapAllocator::getBlockSize (void *block)
00623 {
00624         // Get the node pointer
00625         CNodeBegin *node = (CNodeBegin*) ((uint)block - sizeof (CNodeBegin));
00626 
00627         return getNodeSize (((CNodeBegin*) ((uint)block - sizeof (CNodeBegin))));
00628 }
00629 
00630 // *********************************************************
00631 
00632 const char * CHeapAllocator::getCategory (void *block)
00633 {
00634         // Get the node pointer
00635         CNodeBegin *node = (CNodeBegin*) ((uint)block - sizeof (CNodeBegin));
00636 #ifndef NL_HEAP_ALLOCATION_NDEBUG

bool NLMEMORY::CHeapAllocator::checkNodeSB const CSmallBlockPool mainBlock,
const CNodeBegin previous,
const CNodeBegin current,
const CNodeBegin next,
bool  stopOnError
const [inline, private]
 

Definition at line 474 of file memory/heap_allocator.cpp.

References uint32, and uint8.

00496         {
00497                 // Set previous
00498                 next->Previous = newNode;
00499 
00500                 NL_UPDATE_MAGIC_NUMBER (next);
00501         }
00502 
00503         // Should be big enough
00504         internalAssert (getNodeSize (newNode) >= UserDataBlockSizeMin);
00505 
00506         // New size of the first node
00507         setNodeSize (node, allignedSize);
00508 
00509         // No more the last
00510         setNodeLast (node, false);
00511 
00512         // Return new node
00513         return newNode;
00514 }
00515 
00516 // *********************************************************
00517 
00518 void CHeapAllocator::mergeNode (CNodeBegin *node)
00519 {
00520         // Get the previous node to merge with
00521         CNodeBegin *previous = node->Previous;
00522         internalAssert (getNextNode (previous) == node);
00523         internalAssert (previous);
00524         internalAssert (isNodeFree (previous));
00525 
00526         // New size
00527         setNodeSize (previous, getNodeSize (previous) + getNodeSize (node) + sizeof (CNodeBegin) + NL_HEAP_NODE_END_SIZE);
00528 
00529 #ifndef NL_HEAP_ALLOCATION_NDEBUG
00530         // Set end pointers
00531         previous->EndMagicNumber = (uint32*)((uint8*)previous + getNodeSize (previous) + sizeof (CNodeBegin));
00532 #endif // NL_HEAP_ALLOCATION_NDEBUG
00533 
00534         // Get the next node to relink
00535         CNodeBegin *next = getNextNode (node);
00536         if (next)

void NLMEMORY::CHeapAllocator::computeCRC32 uint32 crc,
const void *  buffer,
unsigned int  count
[inline, static, private]
 

Definition at line 340 of file memory/heap_allocator.cpp.

References isNodeBlack(), isNodeRed(), NL_UPDATE_MAGIC_NUMBER_FREE_NODE, rotateLeft(), rotateRight(), setNodeBlack(), setNodeColor(), setNodeRed(), w, and x.

00341                 {
00342                         if (x == x->Parent->Left)
00343                         {
00344                                 CFreeNode *w = x->Parent->Right;
00345                                 if (isNodeRed (w))
00346                                 {
00347                                         setNodeBlack (w);
00348                                         setNodeRed (x->Parent);
00349                                         rotateLeft (x->Parent);
00350 
00351                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
00352 
00353                                         w = x->Parent->Right;
00354                                 }
00355                                 if (isNodeBlack (w->Left) && isNodeBlack (w->Right))
00356                                 {
00357                                         setNodeRed (w);
00358                                         x = x->Parent;
00359 
00360                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
00361                                 }
00362                                 else
00363                                 {
00364                                         if (isNodeBlack (w->Right))
00365                                         {
00366                                                 setNodeBlack (w->Left);
00367                                                 setNodeRed (w);
00368                                                 rotateRight (w);
00369                                                 w = x->Parent->Right;
00370                                         }

void NLMEMORY::CHeapAllocator::debugAlwaysCheckMemory bool  alwaysCheck  ) 
 

Definition at line 3122 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::debugGetAllocatedMemoryByCategory const char *  category  )  const
 

Definition at line 2160 of file memory/heap_allocator.cpp.

References size, and uint8.

02162 {
02163 #undef malloc
02164         return (uint8*)::malloc (size);
02165 }
02166 
02167 // *********************************************************
02168 
02169 void CHeapAllocator::freeBlock (uint8 *block)
02170 {
02171         ::free (block);
02172 }
02173 
02174 // *********************************************************
02175 
02176 bool CHeapAllocator::internalCheckHeap (bool stopOnError) const
02177 {
02178         enterCriticalSection ();
02179 
02180         // For each small blocks
02181         CSmallBlockPool *pool = (CSmallBlockPool*)_SmallBlockPool;
02182         while (pool)
02183         {
02184                 // For each small block
02185                 uint smallBlock;
02186                 CNodeBegin      *previous = NULL;
02187                 for (smallBlock=0; smallBlock<SmallBlockPoolSize; smallBlock++)
02188                 {
02189                         // Get the small block
02190                         CNodeBegin      *node = getSmallBlock (pool, smallBlock);
02191                         CNodeBegin      *next = (smallBlock+1<SmallBlockPoolSize) ? getSmallBlock (pool, smallBlock+1) : NULL;
02192 
02193                         // Check node
02194                         checkNodeSB (pool, previous, node, next, stopOnError);
02195 
02196                         previous = node;
02197                 }
02198 
02199                 // Next pool
02200                 pool = pool->Next;
02201         }
02202         
02203         // For each main block
02204         CMainBlock *currentBlock = _MainBlockList;
02205         while (currentBlock)
02206         {
02207                 // Get the nodes
02208                 const CNodeBegin *previous = NULL;
02209                 const CNodeBegin *current = getFirstNode (currentBlock);
02210                 internalAssert (current);       // Should have at least one block in the main block
02211                 const CNodeBegin *next;
02212                 
02213                 // For each node

uint NLMEMORY::CHeapAllocator::debugGetDebugInfoSize  )  const
 

Definition at line 2219 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::debugGetLBDebugInfoSize  )  const
 

Definition at line 2225 of file memory/heap_allocator.cpp.

02246 {
02247         _AlwaysCheck = alwaysCheck;
02248 }
02249 #endif // NL_HEAP_ALLOCATION_NDEBUG
02250 
02251 // *********************************************************
02252 
02253 #ifndef NL_HEAP_ALLOCATION_NDEBUG
02254 bool CHeapAllocator::debugIsAlwaysCheckMemory () const
02255 {

uint NLMEMORY::CHeapAllocator::debugGetSBDebugInfoSize  )  const
 

Definition at line 2257 of file memory/heap_allocator.cpp.

02263 {
02264         enterCriticalSection ();
02265 
02266         strncpy (_Name, name, NameLength-1);
02267 
02268         leaveCriticalSection ();
02269 }
02270 
02271 // *********************************************************
02272 // Category control
02273 // *********************************************************
02274 
02275 void CHeapAllocator::debugPushCategoryString (const char *str)
02276 {
02277         // Get the category stack pointer
02278         CCategory *last = (CCategory*)_CategoryStack.getPointer ();

bool NLMEMORY::CHeapAllocator::debugIsAlwaysCheckMemory  )  const
 

Definition at line 3131 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::debugPopCategoryString  ) 
 

Definition at line 3168 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::debugPushCategoryString const char *  str  ) 
 

Definition at line 3152 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::debugReportMemoryLeak  ) 
 

Definition at line 2893 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::debugStatisticsReport const char *  stateFile,
bool  memoryMap
 

Definition at line 2329 of file memory/heap_allocator.cpp.

02333         {
02334                 // ********
02335                 // * STOP *
02336                 // ********
02337                 // * This node is not hold by this heap. It has been allocated with another heap.
02338                 // ********
02339                 // * (*node) Check for more informations
02340                 // ********
02341                 NL_ALLOC_STOP;
02342         }
02343 }
02344 
02345 #ifdef NL_OS_WINDOWS
02346 #pragma optimize( "", on )
02347 #endif // NL_OS_WINDOWS
02348 
02349 #endif // NL_HEAP_ALLOCATION_NDEBUG
02350 
02351 // *********************************************************
02352 
02353 uint CHeapAllocator::getAllocatedSystemMemory ()
02354 {
02355         uint systemMemory = 0;
02356 #ifdef NL_OS_WINDOWS
02357         // Get system memory informations
02358         HANDLE hHeap[100];
02359         DWORD heapCount = GetProcessHeaps (100, hHeap);
02360 
02361         uint heap;
02362         for (heap = 0; heap < heapCount; heap++)
02363         {
02364                 PROCESS_HEAP_ENTRY entry;
02365                 entry.lpData = NULL;
02366                 while (HeapWalk (hHeap[heap], &entry))
02367                 {
02368                         if (entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
02369                         {
02370                                 systemMemory += entry.cbData + entry.cbOverhead;
02371                         }
02372                 }
02373         }
02374 #endif // NL_OS_WINDOWS
02375         return systemMemory;
02376 }
02377 
02378 // *********************************************************
02379 
02380 class CPointerEntry
02381 {
02382 public:
02383         CPointerEntry (void     *pointer, CPointerEntry *entry)
02384         {
02385                 Pointer = pointer;
02386                 Next = entry;
02387         }
02388         static CPointerEntry *find (CPointerEntry *cat, void *pointer)
02389         {
02390                 while (cat)
02391                 {
02392                         if (pointer == cat->Pointer)
02393                                 break;
02394                         cat = cat->Next;
02395                 }
02396                 return cat;
02397         }
02398         void                    *Pointer;
02399         CPointerEntry   *Next;
02400 };
02401 
02402 uint CHeapAllocator::getAllocatedSystemMemoryByAllocator ()
02403 {
02404         uint nelSystemMemory = 0;
02405 
02406         // Build a set of allocated system memory pointers
02407         CPointerEntry *entries = NULL;
02408 
02409         // For each main block
02410         CMainBlock *currentBlock = _MainBlockList;
02411         while (currentBlock)
02412         {
02413                 // Save pointers
02414                 entries = new CPointerEntry ((void*)currentBlock, entries);
02415                 entries = new CPointerEntry ((void*)currentBlock->Ptr, entries);
02416 
02417                 // Next block
02418                 currentBlock = currentBlock->Next;
02419         }
02420 
02421 #ifdef NL_OS_WINDOWS
02422         // Get system memory informations
02423         HANDLE hHeap[100];
02424         DWORD heapCount = GetProcessHeaps (100, hHeap);
02425 
02426         FILE *file = fopen ("dump.bin", "wb");
02427 
02428         uint heap;
02429         for (heap = 0; heap < heapCount; heap++)
02430         {
02431                 PROCESS_HEAP_ENTRY entry;
02432                 entry.lpData = NULL;
02433                 uint block = 0;
02434                 while (HeapWalk (hHeap[heap], &entry))
02435                 {
02436                         if (entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
02437                         {
02438                                 // This pointer is already used ?
02439                                 if ( CPointerEntry::find (entries, (void*)((char*)entry.lpData)) || 
02440                                         CPointerEntry::find (entries, (void*)((char*)entry.lpData+32) ) )
02441                                         nelSystemMemory += entry.cbData + entry.cbOverhead;
02442                                 else
02443                                 {
02444                                         fwrite (entry.lpData, 1, entry.cbData, file);
02445                                 }
02446                         }
02447                         block++;
02448                 }
02449         }
02450         
02451         fclose (file);
02452 
02453 #endif // NL_OS_WINDOWS
02454 
02455         return nelSystemMemory;
02456 }
02457 
02458 // *********************************************************
02459 
02460 uint8 *CHeapAllocator::internalAllocateBlock (uint size)
02461 {
02462         uint8 *ptr = allocateBlock (size);
02463         
02464         return ptr;
02465 }
02466 
02467 // *********************************************************
02468 
02469 void CHeapAllocator::outOfMemory()
02470 {
02471         // Out of memory callback
02472         if (_OutOfMemoryCallback)
02473                 _OutOfMemoryCallback();
02474         
02475         // Select outofmemory mode
02476         if (_OutOfMemoryMode == ThrowException)
02477                 throw 0;
02478 }
02479 
02480 // *********************************************************
02481 
02482 void CHeapAllocator::setOutOfMemoryHook (void (*outOfMemoryCallback)())
02483 {
02484         _OutOfMemoryCallback = outOfMemoryCallback;
02485 }
02486 
02487 // *********************************************************
02488 
02489 } // NLMEMORY
02490 } // NLMEMORY

void NLMEMORY::CHeapAllocator::enterCriticalSection  )  const [inline, private]
 

Definition at line 771 of file memory/heap_allocator.cpp.

00837                 {

void NLMEMORY::CHeapAllocator::enterCriticalSectionLB  )  const [inline, private]
 

Definition at line 757 of file memory/heap_allocator.cpp.

References uint8.

void NLMEMORY::CHeapAllocator::enterCriticalSectionSB  )  const [inline, private]
 

Definition at line 743 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::erase CFreeNode z  )  [inline, private]
 

Definition at line 1128 of file memory/heap_allocator.cpp.

References NL_ALLOC_STOP.

01132                                             :   the already deleted node
01133                                 // ********
01134                                 NL_ALLOC_STOP;
01135                         }
01136                         else
01137                         {
01138                                 enterCriticalSectionLB ();
01139 
01140 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01141                                 // Uninitialised memory
01142                                 memset ((uint8*)node + sizeof(CNodeBegin), DeletedMemory, size );
01143 
01144                                 // Set end pointers
01145                                 node->EndMagicNumber = (uint32*)((uint8*)node + size + sizeof (CNodeBegin));
01146 #endif // NL_HEAP_ALLOCATION_NDEBUG
01147 
01148                                 // Mark has free
01149                                 setNodeFree (node);
01150 
01151                                 // *******************
01152                                 // Large block
01153                                 // *******************
01154 
01155                                 // A free node
01156                                 CHeapAllocator::CFreeNode *freeNode = NULL;
01157 
01158                                 // Previous node
01159                                 CNodeBegin *previous = node->Previous;
01160                                 if (previous)
01161                                 {
01162 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01163                                         // Check the previous node
01164                                         checkNode (previous, evalMagicNumber (previous));
01165 #endif // NL_HEAP_ALLOCATION_NDEBUG
01166 
01167                                         // Is it free ?
01168                                         if (isNodeFree (previous))
01169                                         {
01170                                                 // Merge the two nodes
01171                                                 mergeNode (node);
01172 
01173                                                 // Get its free node
01174                                                 erase (getFreeNode (previous));
01175 
01176                                                 // Curent node
01177                                                 node = previous;
01178                                         }
01179                                 }
01180 
01181                                 // Mark has free
01182                                 setNodeFree (node);
01183 
01184                                 // Next node
01185                                 CNodeBegin *next = getNextNode (node);
01186                                 if (next)
01187                                 {
01188 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01189                                         // Check the next node
01190                                         checkNode (next, evalMagicNumber (next));
01191 #endif // NL_HEAP_ALLOCATION_NDEBUG
01192 
01193                                         // Is it free ?
01194                                         if (isNodeFree (next))
01195                                         {
01196                                                 // Free the new one
01197                                                 erase (getFreeNode (next));
01198 
01199                                                 // Merge the two nodes
01200                                                 mergeNode (next);
01201                                         }
01202                                 }
01203 
01204                                 // Insert it into the tree
01205                                 insert (getFreeNode (node));
01206 
01207                                 NL_UPDATE_MAGIC_NUMBER (node);
01208                                 
01209                                 leaveCriticalSectionLB ();
01210                         }
01211                 }
01212         }
01213 }
01214 
01215 // *********************************************************
01216 // Statistics
01217 // *********************************************************
01218 
01219 uint CHeapAllocator::getAllocatedMemory () const
01220 {
01221         enterCriticalSection ();
01222 
01223         // Sum allocated memory
01224         uint memory = 0;
01225 
01226         // For each small block
01227         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
01228         while (currentSB)
01229         {
01230                 // For each node in this small block pool
01231                 uint block;
01232                 for (block=0; block<SmallBlockPoolSize; block++)
01233                 {
01234                         // Get the node
01235                         const CNodeBegin *current = getSmallBlock (currentSB, block);
01236 
01237                         // Node allocated ?
01238                         if (isNodeUsed (current))
01239                                 memory += getNodeSize (current) + ReleaseHeaderSize;
01240                 }
01241 
01242                 // Next block
01243                 currentSB = currentSB->Next;
01244         }
01245 
01246         // For each main block
01247         CMainBlock *currentBlock = _MainBlockList;
01248         while (currentBlock)
01249         {
01250                 // Get the first node
01251                 const CNodeBegin *current = getFirstNode (currentBlock);
01252                 while (current)
01253                 {
01254 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01255                         // Check node
01256                         checkNode (current, evalMagicNumber (current));
01257 #endif // NL_HEAP_ALLOCATION_NDEBUG
01258 
01259                         // Node allocated ? Don't sum small blocks..
01260                         if (isNodeUsed (current))
01261 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01262                                 if (strcmp (current->Category, NL_HEAP_SB_CATEGORY) != 0)
01263 #endif // NL_HEAP_ALLOCATION_NDEBUG
01264                                         memory += getNodeSize (current) + ReleaseHeaderSize;
01265 
01266                         // Next node
01267                         current = getNextNode (current);
01268                 }
01269 
01270                 // Next block
01271                 currentBlock = currentBlock->Next;
01272         }
01273 
01274         leaveCriticalSection ();
01275 
01276         // Return memory used
01277         return memory;
01278 }
01279 
01280 // *********************************************************
01281 
01282 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01283 uint CHeapAllocator::debugGetAllocatedMemoryByCategory (const char* category) const
01284 {
01285         enterCriticalSection ();
01286 
01287         // Sum allocated memory
01288         uint memory = 0;
01289 
01290         // For each small block
01291         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
01292         while (currentSB)
01293         {
01294                 // For each node in this small block pool
01295                 uint block;
01296                 for (block=0; block<SmallBlockPoolSize; block++)
01297                 {
01298                         // Get the node
01299                         const CNodeBegin *current = getSmallBlock (currentSB, block);
01300 
01301                         // Node allocated ?
01302                         if ((isNodeUsed (current)) && (strcmp (current->Category, category)==0))
01303                                 memory += getNodeSize (current);
01304 

uint32 NLMEMORY::CHeapAllocator::evalMagicNumber const CNodeBegin node  )  [inline, static, private]
 

Definition at line 453 of file memory/heap_allocator.cpp.

References NL_HEAP_NODE_END_SIZE, and uint8.

CHeapAllocator::CFreeNode * NLMEMORY::CHeapAllocator::find uint  size  )  [inline, private]
 

Definition at line 310 of file memory/heap_allocator.cpp.

References internalAssert, y, and z.

00310                 {
00311                         internalAssert (_FreeTreeRoot == z);
00312                         _FreeTreeRoot = y;
00313                 }
00314 
00315                 if (y->Left)
00316                 {
00317                         internalAssert (y->Left->Parent == z);
00318                         y->Left->Parent = y;
00319                         
00320                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Left);
00321                 }
00322                 if (y->Right)
00323                 {
00324                         internalAssert (y->Right->Parent == z);
00325                         y->Right->Parent = y;
00326         
00327                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Right);
00328                 }
00329         }
00330 
00331         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x);
00332         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y);

void NLMEMORY::CHeapAllocator::free void *  ptr  ) 
 

Free a pointer

Definition at line 1896 of file memory/heap_allocator.cpp.

01912 {
01913         enterCriticalSection ();
01914 
01915         // Sum free memory
01916         uint memory = 0;
01917 
01918         // Clear the free tree
01919         _FreeTreeRoot = &_NullNode.FreeNode;
01920 
01921         // For each main block
01922         CMainBlock *currentBlock = _MainBlockList;
01923         while (currentBlock)
01924         {
01925                 // Reinit this block
01926                 initEmptyBlock (*currentBlock);
01927 
01928                 // Get first block
01929                 CNodeBegin *node = getFirstNode (currentBlock);
01930 
01931                 // Insert the free node
01932                 insert (getFreeNode (node));
01933 
01934                 NL_UPDATE_MAGIC_NUMBER (node);
01935 
01936                 // Next block
01937                 currentBlock = currentBlock->Next;
01938         }
01939 
01940         leaveCriticalSection ();
01941 }
01942 
01943 // *********************************************************
01944 
01945 void    CHeapAllocator::releaseMemory ()
01946 {
01947         enterCriticalSection ();
01948 
01949         // Clear the free tree
01950         _FreeTreeRoot = &_NullNode.FreeNode;
01951 
01952         // For each main block
01953         CMainBlock *currentBlock = _MainBlockList;
01954         while (currentBlock)
01955         {
01956                 freeBlock (currentBlock->Ptr);
01957 
01958                 // Next block
01959                 CMainBlock *toDelete = currentBlock;
01960                 currentBlock = toDelete->Next;
01961                 ::free (toDelete);
01962         }
01963 
01964         // Erase block node
01965         _MainBlockList = NULL;
01966 
01967         leaveCriticalSection ();
01968 }
01969 
01970 // *********************************************************
01971 
01972 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01973 
01974 class CLeak
01975 {
01976 public:
01977         
01978         CLeak (const char *name, CLeak *next)
01979         {
01980                 Name = new char[strlen (name)+1];
01981                 strcpy (Name, name);
01982                 Count = 0;
01983                 Memory = 0;
01984                 Next = next;
01985         }
01986 
01987         ~CLeak ()
01988         {
01989                 delete [] Name;
01990                 if (Next)
01991                         delete Next;
01992         }
01993 
01994         static CLeak *find (CLeak *cat, const char *name)
01995         {
01996                 while (cat)
01997                 {
01998                         if (strcmp (name, cat->Name) == 0)
01999                                 break;
02000                         cat = cat->Next;
02001                 }
02002                 return cat;
02003         }
02004 
02005         static CLeak *insert (const char *name, CLeak *next)
02006         {
02007                 return new CLeak (name, next);
02008         }
02009 
02010         uint                    Count;
02011         uint                    Memory;
02012         char                    *Name;
02013         CLeak                   *Next;
02014 };
02015 
02016 void CHeapAllocator::debugReportMemoryLeak ()
02017 {
02018         debugPushCategoryString (NL_HEAP_MEM_DEBUG_CATEGORY);
02019 
02020         // Sum allocated memory
02021         uint memory = 0;
02022 
02023         // Leak map
02024         CLeak *leakMap = NULL;
02025 
02026         // Header
02027         char report[2048];
02028         sprintf (report, "Report Memory leak for allocator \"%s\"\n", _Name);
02029         CHeapAllocatorOutputError (report);
02030 
02031         // For each small block
02032         CMainBlock *currentBlock = _MainBlockList;
02033         while (currentBlock)
02034         {
02035                 // Get the first node
02036                 const CNodeBegin *current = getFirstNode (currentBlock);
02037                 while (current)
02038                 {
02039                         // Check node
02040                         checkNode (current, evalMagicNumber (current));
02041 
02042                         // Node allocated ?
02043                         if (isNodeUsed (current) && ( (current->Category == NULL) || (current->Category[0] != '_')) )
02044                         {
02045                                 // Make a report
02046                                 sprintf (report, "%s(%d)\t: \"%s\"", current->File, current->Line, current->Category);
02047 
02048                                 // Look for this leak
02049                                 CLeak *ite = CLeak::find (leakMap, report);
02050 
02051                                 // Not found ?
02052                                 if (ite == NULL)
02053                                 {
02054                                         ite = CLeak::insert (report, leakMap);
02055                                         leakMap = ite;
02056                                         ite->Count = 0;
02057                                         ite->Memory = 0;
02058                                 }
02059 
02060                                 // One more leak
02061                                 ite->Count++;
02062                                 ite->Memory += getNodeSize (current);
02063 
02064                                 memory += getNodeSize (current);
02065                         }
02066 
02067                         // Next node
02068                         current = getNextNode (current);
02069                 }
02070 
02071                 // Next block
02072                 currentBlock = currentBlock->Next;
02073         }
02074 
02075         // For each small block
02076         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
02077         while (currentSB)
02078         {
02079                 // For each node in this small block pool
02080                 uint block;
02081                 for (block=0; block<SmallBlockPoolSize; block++)
02082                 {
02083                         // Get the node
02084                         const CNodeBegin *current = getSmallBlock (currentSB, block);
02085                         // Check node
02086                         checkNode (current, evalMagicNumber (current));
02087 
02088                         // Node allocated ?
02089                         if (isNodeUsed (current) && ( (current->Category == NULL) || (current->Category[0] != '_')) )
02090                         {

void NLMEMORY::CHeapAllocator::freeAll  ) 
 

Free all the block allocated

Definition at line 2788 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::freeBlock uint8 block  )  [virtual]
 

Method used to free system memory

Definition at line 3046 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::getAllocatedMemory  )  const
 

Definition at line 2096 of file memory/heap_allocator.cpp.

02099                                 {
02100                                         ite = CLeak::insert (report, leakMap);
02101                                         leakMap = ite;
02102                                         ite->Count = 0;
02103                                         ite->Memory = 0;
02104                                 }
02105 
02106                                 // One more leak
02107                                 ite->Count++;
02108                                 ite->Memory += getNodeSize (current);
02109 
02110                                 memory += getNodeSize (current);
02111                         }
02112                 }
02113 
02114                 // Next block
02115                 currentSB = currentSB->Next;
02116         }
02117 
02118         // Look for this leak
02119         CLeak *ite = leakMap;
02120         while (ite)
02121         {
02122                 // Make a report
02123                 sprintf (report, "%s,\tLeak count : %d,\tMemory allocated : %d\n", ite->Name, ite->Count, ite->Memory);
02124 
02125                 // Report on stderr
02126                 CHeapAllocatorOutputError (report);
02127 
02128                 ite = ite->Next;
02129         }
02130 
02131         // Make a report
02132         if (memory)
02133         {
02134                 sprintf (report, "%d byte(s) found\n", memory);
02135         }
02136         else
02137         {
02138                 sprintf (report, "No memory leak\n");
02139         }
02140         CHeapAllocatorOutputError (report);
02141 
02142         // Delete list
02143         if (leakMap)
02144                 delete leakMap;
02145 
02146         debugPopCategoryString ();
02147 }
02148 #endif // NL_HEAP_ALLOCATION_NDEBUG
02149 
02150 // *********************************************************
02151 
02152 bool CHeapAllocator::checkHeap (bool stopOnError) const
02153 {
02154         bool res = internalCheckHeap (stopOnError);
02155 

uint NLMEMORY::CHeapAllocator::getAllocatedSystemMemory  )  [static]
 

Definition at line 3230 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::getAllocatedSystemMemoryByAllocator  ) 
 

Definition at line 3279 of file memory/heap_allocator.cpp.

CHeapAllocator::TBlockAllocationMode NLMEMORY::CHeapAllocator::getBlockAllocationMode  )  const [inline]
 

Definition at line 871 of file memory/heap_allocator.cpp.

References NL_HEAP_NODE_END_SIZE, size, and uint.

00871                                                                                                              : Align);
00872                                         if (allignedSize < BlockDataSizeMin)
00873                                                 allignedSize = BlockDataSizeMin;
00874 

uint NLMEMORY::CHeapAllocator::getBlockSize void *  block  )  [static]
 

Get a block size with its pointer

Definition at line 1499 of file memory/heap_allocator.cpp.

References size.

01515                 {

const char * NLMEMORY::CHeapAllocator::getCategory void *  block  )  [static]
 

Get a block category from its pointer

Definition at line 1509 of file memory/heap_allocator.cpp.

01515                 {
01516                         // Get the first node
01517                         const CNodeBegin *current = getFirstNode (currentBlock);
01518                         while (current)

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getFirstNode CMainBlock mainBlock  )  [inline, static, private]
 

Definition at line 384 of file memory/heap_allocator.cpp.

References NL_UPDATE_MAGIC_NUMBER_FREE_NODE, rotateRight(), setNodeBlack(), setNodeRed(), w, and x.

00386                                 {
00387                                         setNodeBlack (w);
00388                                         setNodeRed (x->Parent);

const CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getFirstNode const CMainBlock mainBlock  )  [inline, static, private]
 

Definition at line 376 of file memory/heap_allocator.cpp.

References w, and x.

00383                         {

float NLMEMORY::CHeapAllocator::getFragmentationRatio  )  const
 

Definition at line 2747 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::getFreeMemory  )  const
 

Definition at line 2628 of file memory/heap_allocator.cpp.

CHeapAllocator::CFreeNode * NLMEMORY::CHeapAllocator::getFreeNode CNodeBegin current  )  [inline, static, private]
 

Definition at line 423 of file memory/heap_allocator.cpp.

const CHeapAllocator::CFreeNode * NLMEMORY::CHeapAllocator::getFreeNode const CNodeBegin current  )  [inline, static, private]
 

Definition at line 416 of file memory/heap_allocator.cpp.

References w, and x.

uint NLMEMORY::CHeapAllocator::getMainBlockCount  )  const [inline]
 

Get the block count

Definition at line 808 of file memory/heap_allocator.cpp.

References NLMEMORY::line, size, uint, uint32, and uint8.

00837                 {

uint NLMEMORY::CHeapAllocator::getMainBlockSize  )  const [inline]
 

Get the size of the block

Definition at line 886 of file memory/heap_allocator.cpp.

References buffer.

00888                                         {
00889                                                 leaveCriticalSectionLB ();

const char * NLMEMORY::CHeapAllocator::getName  )  const [inline]
 

Definition at line 879 of file memory/heap_allocator.cpp.

References buffer.

00888                                         {

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getNextNode CNodeBegin current  )  [inline, static, private]
 

Definition at line 404 of file memory/heap_allocator.cpp.

References rotateLeft(), setNodeBlack(), setNodeRed(), w, and x.

00405                                         {
00406                                                 setNodeBlack (w->Right);
00407                                                 setNodeRed (w);
00408                                                 rotateLeft (w);
00409                                                 w = x->Parent->Left;
00410                                         }
00411                                         setNodeColor (w, isNodeRed (x->Parent) );
00412                                         setNodeBlack (x->Parent);

const CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getNextNode const CNodeBegin current  )  [inline, static, private]
 

Definition at line 392 of file memory/heap_allocator.cpp.

References w, and x.

00396                                 {
00397                                         setNodeRed (w);
00398                                         x = x->Parent;
00399 
00400                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getNextSmallBlock CNodeBegin previous  )  [inline, static, private]
 

Definition at line 903 of file memory/heap_allocator.cpp.

00917                                 {

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getNode CFreeNode current  )  [inline, static, private]
 

Definition at line 437 of file memory/heap_allocator.cpp.

References Align, uint, and UserDataBlockSizeMin.

00439                                                                                    : Align);
00440         if (allignedSize <= UserDataBlockSizeMin)

const CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getNode const CFreeNode current  )  [inline, static, private]
 

Definition at line 430 of file memory/heap_allocator.cpp.

References internalAssert, and uint.

00434 {

uint NLMEMORY::CHeapAllocator::getNodeSize const CNodeBegin current  )  [inline, static, private]
 

Definition at line 444 of file memory/heap_allocator.cpp.

References NL_HEAP_NODE_END_SIZE, uint32, and uint8.

CHeapAllocator::TOutOfMemoryMode NLMEMORY::CHeapAllocator::getOutOfMemoryMode  )  const [inline]
 

Definition at line 853 of file memory/heap_allocator.cpp.

00855                                 {
00856                                         // Block allocation mode

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::getSmallBlock CSmallBlockPool smallBlock,
uint  blockIndex
[inline, static, private]
 

Definition at line 896 of file memory/heap_allocator.cpp.

00899                                         {

uint NLMEMORY::CHeapAllocator::getSmallBlockMemory  )  const
 

Definition at line 2720 of file memory/heap_allocator.cpp.

uint NLMEMORY::CHeapAllocator::getTotalMemoryUsed  )  const
 

Definition at line 2691 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::initEmptyBlock CMainBlock mainBlock  )  [inline, private]
 

Definition at line 1444 of file memory/heap_allocator.cpp.

References uint.

01453 {
01454         // Status
01455         bool status = false;
01456 
01457         debugPushCategoryString (NL_HEAP_MEM_DEBUG_CATEGORY);
01458 
01459         // Open files
01460         FILE *file = fopen (stateFile, "wt");
01461 
01462         // List of category
01463         CCategoryMap *catMap = NULL;
01464 
01465         // Both OK
01466         if (file)
01467         {
01468                 // **************************
01469 
01470                 // For each small block
01471                 uint smallBlockCount = 0;
01472                 uint largeBlockCount = 0;
01473                 CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
01474                 while (currentSB)
01475                 {
01476                         // For each node in this small block pool
01477                         uint block;
01478                         for (block=0; block<SmallBlockPoolSize; block++)
01479                         {
01480                                 // Get the node
01481                                 const CNodeBegin *current = getSmallBlock (currentSB, block);
01482 
01483                                 // Node allocated ?
01484                                 if (isNodeUsed (current))
01485                                 {
01486                                         // Find the node
01487                                         CCategoryMap *cat = CCategoryMap::find (catMap, (const char*)current->Category);
01488 
01489                                         // Found ?
01490                                         if (cat == NULL)
01491                                         {
01492                                                 catMap = CCategoryMap::insert (current->Category, catMap);
01493                                                 cat = catMap;
01494                                         }
01495                                         uint size = getNodeSize (current) + ReleaseHeaderSize;

void NLMEMORY::CHeapAllocator::insert CFreeNode x  )  [inline, private]
 

Definition at line 1005 of file memory/heap_allocator.cpp.

References NL_ALLOC_STOP.

01006         {
01007                 // ********
01008                 // * STOP *
01009                 // ********
01010                 // * Attempt to allocate 0 bytes
01011                 // ********
01012                 NL_ALLOC_STOP;
01013                 return NULL;
01014         }
01015 }
01016 
01017 // *********************************************************
01018 
01019 void CHeapAllocator::free (void *ptr)
01020 {
01021         // Delete a null pointer ?
01022         if (ptr == NULL)
01023         {
01024                 // ********
01025                 // * STOP *
01026                 // ********
01027                 // * Attempt to delete a NULL pointer
01028                 // ********
01029 #ifdef NL_HEAP_STOP_NULL_FREE
01030                 NL_ALLOC_STOP;
01031 #endif // NL_HEAP_STOP_NULL_FREE
01032         }
01033         else
01034         {
01035 
01036 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01037                 // Checks ?
01038                 if (_AlwaysCheck)
01039                 {
01040                         // Check heap integrity
01041                         internalCheckHeap (true);
01042                 }
01043 #endif // NL_HEAP_ALLOCATION_NDEBUG
01044                 
01045                 // Get the node pointer
01046                 CNodeBegin *node = (CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin));
01047 
01048                 /* trap debug if (strcmp(getCategory(ptr),"3dIns") == 0)
01049                 {
01050                         n3dDrvTotal -= getNodeSize(node);
01051                         uint dbg= 0;
01052                         dbg++;
01053                 } */
01054 
01055 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01056                 // Check the node CRC
01057                 enterCriticalSectionSB ();
01058                 enterCriticalSectionLB ();
01059                 checkNode (node, evalMagicNumber (node));
01060                 leaveCriticalSectionLB ();
01061                 leaveCriticalSectionSB ();
01062 #endif // NL_HEAP_ALLOCATION_NDEBUG
01063 
01064                 // Large or small block ?
01065 #ifdef NL_HEAP_ALLOCATION_NDEBUG
01066                 uint size = (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))))->SizeAndFlags;
01067 #else // NL_HEAP_ALLOCATION_NDEBUG
01068                 uint size = getNodeSize (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))));
01069 #endif // NL_HEAP_ALLOCATION_NDEBUG
01070                 if (size <= LastSmallBlock)
01071                 {
01072                         // *******************
01073                         // Small block
01074                         // *******************
01075 
01076                         // Check the node has not been deleted
01077                         if (isNodeFree (node))
01078                         {
01079                                 // ********
01080                                 // * STOP *
01081                                 // ********
01082                                 // * Attempt to delete a pointer already deleted
01083                                 // ********
01084                                 // * (*node):   the already deleted node
01085                                 // ********
01086                                 NL_ALLOC_STOP;
01087                         }
01088                         else
01089                         {
01090                                 enterCriticalSectionSB ();
01091 
01092 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01093                                 // Uninitialised memory
01094                                 memset ((uint8*)node + sizeof(CNodeBegin), DeletedMemory, size );
01095 
01096                                 // Set end pointers
01097                                 node->EndMagicNumber = (uint32*)((uint8*)node + size + sizeof (CNodeBegin));
01098 
01099                                 // Mark has free
01100                                 setNodeFree (node);
01101 #endif // NL_HEAP_ALLOCATION_NDEBUG
01102 
01103                                 // Add in the free list
01104                                 CNodeBegin **freeNode = (CNodeBegin **)_FreeSmallBlocks+NL_SIZE_TO_SMALLBLOCK_INDEX (size);
01105                                 ((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin)))->Previous = *freeNode;
01106                                 *freeNode = ((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin)));
01107 
01108                                 // Update smallblock crc
01109                                 NL_UPDATE_MAGIC_NUMBER (node);
01110 
01111                                 leaveCriticalSectionSB ();
01112                         }
01113                 }
01114                 else
01115                 {
01116 #ifdef NL_HEAP_ALLOCATION_NDEBUG
01117                         // Get the real size
01118                         size = getNodeSize (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))));
01119 #endif // NL_HEAP_ALLOCATION_NDEBUG
01120 
01121                         // Get the node pointer
01122                         CNodeBegin *node = (CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin));
01123 
01124                         // Check the node has not been deleted

uint8 * NLMEMORY::CHeapAllocator::internalAllocateBlock uint  size  )  [private]
 

Method used to allocate system memory. Calls allocateBlock.

Definition at line 3337 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::internalCheckHeap bool  stopOnError  )  const [private]
 

Definition at line 3053 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::isNodeBlack const CFreeNode current  )  [inline, static, private]
 

Definition at line 145 of file memory/heap_allocator.cpp.

References x.

Referenced by computeCRC32().

00149         {

bool NLMEMORY::CHeapAllocator::isNodeFree const CNodeBegin current  )  [inline, static, private]
 

Definition at line 106 of file memory/heap_allocator.cpp.

bool NLMEMORY::CHeapAllocator::isNodeLast const CNodeBegin current  )  [inline, static, private]
 

Definition at line 120 of file memory/heap_allocator.cpp.

References releaseMemory().

00121 {
00122         // Release all memory used
00123         releaseMemory ();

bool NLMEMORY::CHeapAllocator::isNodeRed const CFreeNode current  )  [inline, static, private]
 

Definition at line 138 of file memory/heap_allocator.cpp.

Referenced by computeCRC32(), and setNodeLast().

00138                                                                                                           : current->Right;
00139         }
00140 
00141         // Setup new node

bool NLMEMORY::CHeapAllocator::isNodeSmall const CNodeBegin current  )  [inline, static, private]
 

Definition at line 127 of file memory/heap_allocator.cpp.

References _FreeTreeRoot, _NullNode, NLMEMORY::CHeapAllocator::CNullNode::FreeNode, and x.

00129 {
00130     CHeapAllocator::CFreeNode *current, *parent;
00131 
00132     // Find future parent
00133         current = _FreeTreeRoot;
00134         parent = NULL;

bool NLMEMORY::CHeapAllocator::isNodeUsed const CNodeBegin current  )  [inline, static, private]
 

Definition at line 113 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::leaveCriticalSection  )  const [inline, private]
 

Definition at line 779 of file memory/heap_allocator.cpp.

00837                 {

void NLMEMORY::CHeapAllocator::leaveCriticalSectionLB  )  const [inline, private]
 

Definition at line 764 of file memory/heap_allocator.cpp.

References uint8.

00837                 {

void NLMEMORY::CHeapAllocator::leaveCriticalSectionSB  )  const [inline, private]
 

Definition at line 750 of file memory/heap_allocator.cpp.

References uint32, and uint8.

void NLMEMORY::CHeapAllocator::mergeNode CNodeBegin node  )  [inline, static, private]
 

Definition at line 1395 of file memory/heap_allocator.cpp.

01407 {
01408         
01409 }
01410 
01411 // *********************************************************
01412 
01413 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01414 
01415 class CCategoryMap
01416 {
01417 public:
01418         CCategoryMap (const char *name, CCategoryMap *next)
01419         {
01420                 Name = name;
01421                 BlockCount = 0;
01422                 Size = 0;
01423                 Min = 0xffffffff;
01424                 Max = 0;
01425                 Next = next;
01426         }
01427 
01428         static CCategoryMap *find (CCategoryMap *cat, const char *name)
01429         {
01430                 while (cat)
01431                 {
01432                         if (strcmp (name, cat->Name) == 0)

void NLMEMORY::CHeapAllocator::outOfMemory  )  [private]
 

Method used when no memory is available

Definition at line 3346 of file memory/heap_allocator.cpp.

void* NLMEMORY::CHeapAllocator::reallocate void *  ptr,
uint  size,
const char *  sourceFile,
uint  line,
const char *  category
 

void NLMEMORY::CHeapAllocator::releaseMemory  ) 
 

Todo:
Free all the block allocated and release all the memory used by the allocator

Definition at line 2822 of file memory/heap_allocator.cpp.

Referenced by isNodeLast().

void NLMEMORY::CHeapAllocator::rotateLeft CFreeNode x  )  [inline, private]
 

Definition at line 214 of file memory/heap_allocator.cpp.

References x.

Referenced by computeCRC32(), getNextNode(), and setNodeColor().

00226                         {
00227                 // Uncle is Black
00228                 if (x == x->Parent->Left) 
00229                                 {
00230                     x = x->Parent;                    
00231                                         rotateRight(x);
00232                 }
00233                                 setNodeBlack (x->Parent);
00234                 setNodeRed (x->Parent->Parent);
00235 
00236                 rotateLeft (x->Parent->Parent);
00237 
00238                                 // Crc node
00239                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent);
00240                         }        
00241                 }    
00242         }
00243     setNodeBlack (_FreeTreeRoot);
00244 
00245         // Crc node
00246         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (_FreeTreeRoot);
00247 }
00248 
00249 // *********************************************************
00250 
00251 void CHeapAllocator::erase (CHeapAllocator::CFreeNode *z)
00252 {
00253         CFreeNode *x, *y;
00254         if (z->Left == &_NullNode.FreeNode || z->Right == &_NullNode.FreeNode)
00255         {
00256                 // y has a NULL node as a child

void NLMEMORY::CHeapAllocator::rotateRight CFreeNode x  )  [inline, private]
 

Definition at line 260 of file memory/heap_allocator.cpp.

References _NullNode, NLMEMORY::CHeapAllocator::CNullNode::FreeNode, y, and z.

Referenced by computeCRC32(), and getFirstNode().

00260         {
00261                 // Find tree successor with a &_NullNode.FreeNode node as a child
00262                 y = z->Right;
00263                 while (y->Left != &_NullNode.FreeNode)
00264                         y = y->Left;
00265         }
00266         
00267         // x is y's only child
00268         if (y->Left != &_NullNode.FreeNode)
00269                 x = y->Left;
00270         else
00271                 x = y->Right;
00272 
00273         // Remove y from the parent chain
00274         x->Parent = y->Parent;
00275 
00276         if (y->Parent)
00277         {
00278                 if (y == y->Parent->Left)
00279                         y->Parent->Left = x;
00280                 else
00281                 {
00282                         internalAssert (y == y->Parent->Right);
00283                         y->Parent->Right = x;
00284                 }
00285                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Parent);
00286         }
00287         else
00288                 _FreeTreeRoot = x;
00289 
00290         bool yRed = isNodeRed (y);
00291 
00292         if (y != z)
00293         {
00294                 // Replace y by z
00295                 *y = *z;
00296                 setNodeColor (y, isNodeRed (z));
00297                 if (y->Parent)
00298                 {
00299                         if (y->Parent->Left == z)
00300                         {
00301                                 y->Parent->Left = y;
00302                         }
00303                         else
00304                         {
00305                                 internalAssert (y->Parent->Right == z);
00306                                 y->Parent->Right = y;

void NLMEMORY::CHeapAllocator::setBlockAllocationMode TBlockAllocationMode  mode  )  [inline]
 

Definition at line 860 of file memory/heap_allocator.cpp.

00871                                                                                                              : Align);

bool NLMEMORY::CHeapAllocator::setMainBlockCount uint  blockCount  ) 
 

Set the block count

bool NLMEMORY::CHeapAllocator::setMainBlockSize uint  mainBlockSize  ) 
 

Returns false if the block size choosed i too big (>= 1 Go)

void NLMEMORY::CHeapAllocator::setName const char *  name  ) 
 

Definition at line 3139 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::setNextSmallBlock CNodeBegin previous,
CNodeBegin next
[inline, static, private]
 

Definition at line 910 of file memory/heap_allocator.cpp.

00917                                 {

void NLMEMORY::CHeapAllocator::setNodeBlack CFreeNode current  )  [inline, static, private]
 

Definition at line 205 of file memory/heap_allocator.cpp.

Referenced by computeCRC32(), getFirstNode(), and getNextNode().

00208                 {

void NLMEMORY::CHeapAllocator::setNodeColor CFreeNode current,
bool  red
[inline, static, private]
 

Definition at line 188 of file memory/heap_allocator.cpp.

References rotateLeft(), and x.

Referenced by computeCRC32().

00188                         {
00189                 // Uncle is Black
00190                                 if (x == x->Parent->Right)
00191                                 {
00192                     // Make x a left child
00193                                         x = x->Parent;
00194                     rotateLeft(x);

void NLMEMORY::CHeapAllocator::setNodeFree CNodeBegin current  )  [inline, static, private]
 

Definition at line 152 of file memory/heap_allocator.cpp.

References x.

00157         {

void NLMEMORY::CHeapAllocator::setNodeLast CNodeBegin current,
bool  last
[inline, static, private]
 

Definition at line 166 of file memory/heap_allocator.cpp.

References isNodeRed(), x, and y.

00168         {
00169                 // We have a violation
00170                 if (x->Parent == x->Parent->Parent->Left)
00171                 {
00172                         CHeapAllocator::CFreeNode *y = x->Parent->Parent->Right;

void NLMEMORY::CHeapAllocator::setNodeRed CFreeNode current  )  [inline, static, private]
 

Definition at line 198 of file memory/heap_allocator.cpp.

References x.

Referenced by computeCRC32(), getFirstNode(), and getNextNode().

00208                 {

void NLMEMORY::CHeapAllocator::setNodeSize CNodeBegin current,
uint  size
[inline, static, private]
 

Definition at line 176 of file memory/heap_allocator.cpp.

References x.

00188                         {

void NLMEMORY::CHeapAllocator::setNodeUsed CNodeBegin current  )  [inline, static, private]
 

Definition at line 159 of file memory/heap_allocator.cpp.

00168         {

void NLMEMORY::CHeapAllocator::setOutOfMemoryHook void(*  outOfMemoryCallback)()  ) 
 

Definition at line 3359 of file memory/heap_allocator.cpp.

void NLMEMORY::CHeapAllocator::setOutOfMemoryMode TOutOfMemoryMode  mode  )  [inline]
 

Definition at line 842 of file memory/heap_allocator.cpp.

References size.

00844                         {
00845                                 enterCriticalSectionLB ();
00846 
00847                                 // Find a free node
00848                                 CHeapAllocator::CFreeNode *freeNode = CHeapAllocator::find (size);
00849 

CHeapAllocator::CNodeBegin * NLMEMORY::CHeapAllocator::splitNode CNodeBegin node,
uint  newSize
[inline, private]
 

Definition at line 1310 of file memory/heap_allocator.cpp.

01315         {
01316                 // Get the first node
01317                 const CNodeBegin *current = getFirstNode (currentBlock);
01318                 while (current)
01319                 {
01320                         // Node allocated ?
01321                         if ((isNodeUsed (current)) && (strcmp (current->Category, category)==0))
01322                                 memory += getNodeSize (current);
01323 
01324                         // Next node
01325                         current = getNextNode (current);
01326                 }
01327 
01328                 // Next block
01329                 currentBlock = currentBlock->Next;
01330         }
01331 
01332         leaveCriticalSection ();
01333 
01334         // Return memory used
01335         return memory;
01336 }
01337 #endif // NL_HEAP_ALLOCATION_NDEBUG
01338 
01339 // *********************************************************
01340 
01341 #ifndef NL_HEAP_ALLOCATION_NDEBUG
01342 uint CHeapAllocator::debugGetDebugInfoSize () const
01343 {
01344         // Return memory used
01345         return debugGetSBDebugInfoSize () + debugGetLBDebugInfoSize ();
01346 }
01347 
01348 uint CHeapAllocator::debugGetLBDebugInfoSize () const
01349 {
01350         enterCriticalSection ();
01351 
01352         // Sum memory used by debug header
01353         uint memory = 0;
01354 
01355         // For each main block
01356         CMainBlock *currentBlock = _MainBlockList;
01357         while (currentBlock)
01358         {
01359                 // Get the first node
01360                 const CNodeBegin *current = getFirstNode (currentBlock);
01361                 while (current)
01362                 {
01363                         // Node allocated ?
01364                         memory  += sizeof(CNodeBegin) - ReleaseHeaderSize + sizeof(CNodeEnd);
01365 
01366                         // Next node
01367                         current = getNextNode (current);
01368                 }
01369 
01370                 // Next block
01371                 currentBlock = currentBlock->Next;
01372         }
01373 
01374         leaveCriticalSection ();
01375 
01376         // Return memory used
01377         return memory;
01378 }
01379 
01380 uint CHeapAllocator::debugGetSBDebugInfoSize () const
01381 {
01382         enterCriticalSection ();
01383 
01384         // Sum memory used by debug header
01385         uint memory = 0;
01386 
01387         // For each small blocks
01388         CSmallBlockPool *pool = (CSmallBlockPool*)_SmallBlockPool;
01389         while (pool)
01390         {
01391                 memory  += SmallBlockPoolSize * (sizeof(CNodeBegin) - ReleaseHeaderSize + sizeof(CNodeEnd));


Friends And Related Function Documentation

friend struct CNodeBegin [friend]
 

Definition at line 274 of file src/memory/heap_allocator.h.


Field Documentation

uint32 NLMEMORY::CHeapAllocator::_AllocateCount [private]
 

Definition at line 442 of file src/memory/heap_allocator.h.

bool NLMEMORY::CHeapAllocator::_AlwaysCheck [private]
 

Definition at line 429 of file src/memory/heap_allocator.h.

TBlockAllocationMode NLMEMORY::CHeapAllocator::_BlockAllocationMode [private]
 

Definition at line 426 of file src/memory/heap_allocator.h.

uint NLMEMORY::CHeapAllocator::_BlockCount [private]
 

Definition at line 425 of file src/memory/heap_allocator.h.

CMemoryTDS NLMEMORY::CHeapAllocator::_CategoryStack [private]
 

Definition at line 533 of file src/memory/heap_allocator.h.

volatile CNodeBegin* NLMEMORY::CHeapAllocator::_FreeSmallBlocks[ (1+(LastSmallBlock - FirstSmallBlock)/SmallBlockGranularity) ] [private]
 

Definition at line 506 of file src/memory/heap_allocator.h.

CFreeNode* NLMEMORY::CHeapAllocator::_FreeTreeRoot [private]
 

Definition at line 436 of file src/memory/heap_allocator.h.

Referenced by isNodeSmall().

CMainBlock* NLMEMORY::CHeapAllocator::_MainBlockList [private]
 

Definition at line 433 of file src/memory/heap_allocator.h.

uint NLMEMORY::CHeapAllocator::_MainBlockSize [private]
 

Definition at line 424 of file src/memory/heap_allocator.h.

CMemoryMutex NLMEMORY::CHeapAllocator::_MutexLB [mutable, private]
 

Definition at line 438 of file src/memory/heap_allocator.h.

CMemoryMutex NLMEMORY::CHeapAllocator::_MutexSB [mutable, private]
 

Definition at line 509 of file src/memory/heap_allocator.h.

char NLMEMORY::CHeapAllocator::_Name[NameLength] [private]
 

Definition at line 440 of file src/memory/heap_allocator.h.

CNullNode NLMEMORY::CHeapAllocator::_NullNode [private]
 

Definition at line 437 of file src/memory/heap_allocator.h.

Referenced by isNodeSmall(), and rotateRight().

void(* NLMEMORY::CHeapAllocator::_OutOfMemoryCallback)() [private]
 

TOutOfMemoryMode NLMEMORY::CHeapAllocator::_OutOfMemoryMode [private]
 

Definition at line 427 of file src/memory/heap_allocator.h.

volatile CSmallBlockPool* NLMEMORY::CHeapAllocator::_SmallBlockPool [private]
 

Definition at line 507 of file src/memory/heap_allocator.h.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 12:56:17 2004 for NeL by doxygen 1.3.6