From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/a02609.html | 5972 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5972 insertions(+) create mode 100644 docs/doxygen/nel/a02609.html (limited to 'docs/doxygen/nel/a02609.html') diff --git a/docs/doxygen/nel/a02609.html b/docs/doxygen/nel/a02609.html new file mode 100644 index 00000000..8539cf5b --- /dev/null +++ b/docs/doxygen/nel/a02609.html @@ -0,0 +1,5972 @@ + + +NeL: NLMISC::CHeapAllocator class Reference + + + +
+

NLMISC::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
volatile CNodeBegin_FreeSmallBlocks [(1+(LastSmallBlock-FirstSmallBlock)/SmallBlockGranularity)]
CAllocatorMutex _MutexSB
volatile CSmallBlockPool_SmallBlockPool
CNodeBegingetNextSmallBlock (CNodeBegin *previous)
CNodeBegingetSmallBlock (CSmallBlockPool *smallBlock, uint blockIndex)
void setNextSmallBlock (CNodeBegin *previous, CNodeBegin *next)

Category control

void debugPopCategoryString ()
void debugPushCategoryString (const char *str)
CTDS _CategoryStack

Public Types

enum  {
+  ReleaseHeaderSize = 8, +CategoryStringLength = 8, +BeginNodeMarkers = '<', +EndNodeMarkers = '>', +
+  UnallocatedMemory = 0xba, +UninitializedMemory = 0xbc, +DeletedMemory = 0xbd, +NameLength = 32 +
+ }
enum  TBlockAllocationMode { Grow, +DontGrow + }
typedef char TCategoryString [CategoryStringLength]
enum  TOutOfMemoryMode { ThrowException, +ReturnNull + }

Public Member Functions

void * allocate (uint size, const char *sourceFile, uint line, const char *category)
virtual uint8allocateBlock (uint size)
 CHeapAllocator (uint mainBlockSize=1024 *1024 *10, uint blockCount=1, TBlockAllocationMode blockAllocationMode=Grow, TOutOfMemoryMode outOfMemoryMode=ThrowException)
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 (bool alwaysCheck) const
void debugReportMemoryLeak ()
bool debugStatisticsReport (const char *stateFile, bool memoryMap)
void free (void *ptr)
void freeAll ()
virtual void freeBlock (uint8 *block)
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 * reallocate (void *ptr, uint size, const char *sourceFile, uint line, const char *category)
void releaseMemory ()
void setBlockAllocationMode (TBlockAllocationMode mode)
bool setMainBlockCount (uint blockCount)
bool setMainBlockSize (uint mainBlockSize)
void setName (const char *name)
void setOutOfMemoryMode (TOutOfMemoryMode mode)
virtual ~CHeapAllocator ()

Static Public Member Functions

uint getAllocatedSystemMemory ()
uint getBlockSize (void *block)

Private Types

enum  { FreeNodeBlockSize = 128, +FreeNodeBlockSizeShift = 7, +FreeNodeBlockSizeMask = 0x7f + }
enum  { Align = 8, +BlockDataSizeMin = 1<<4 + }
enum  { UserDataBlockSizeMin = sizeof(CFreeNode) + }

Private Member Functions

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)

Static Private Member Functions

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)

Private Attributes

uint32 _AllocateCount
bool _AlwaysCheck
TBlockAllocationMode _BlockAllocationMode
uint _BlockCount
CFreeNode_FreeTreeRoot
CMainBlock_MainBlockList
uint _MainBlockSize
CAllocatorMutex _MutexLB
char _Name [NameLength]
CNullNode _NullNode
TOutOfMemoryMode _OutOfMemoryMode
+


Member Typedef Documentation

+

+ + + + +
+ + +
typedef char NLMISC::CHeapAllocator::TCategoryString[CategoryStringLength] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 106 of file include/nel/misc/heap_allocator.h.

+


Member Enumeration Documentation

+

+ + + + +
+ + +
anonymous enum +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + + + + + + + + +
ReleaseHeaderSize  +
CategoryStringLength  +
BeginNodeMarkers  +
EndNodeMarkers  +
UnallocatedMemory  +
UninitializedMemory  +
DeletedMemory  +
NameLength  +
+
+ +

+Definition at line 70 of file include/nel/misc/heap_allocator.h. +

+

00071         { 
+00072                 ReleaseHeaderSize               =       8,
+00073                 CategoryStringLength    =       8,
+00074                 BeginNodeMarkers                =       '<',
+00075                 EndNodeMarkers                  =       '>',
+00076                 UnallocatedMemory               =       0xba,
+00077                 UninitializedMemory             =       0xbc,
+00078                 DeletedMemory                   =       0xbd,
+00079                 NameLength                              =       32
+00080         };
+
+

+ + + + +
+ + +
anonymous enum [private] +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + + + +
FreeNodeBlockSize  +
FreeNodeBlockSizeShift  +
FreeNodeBlockSizeMask  +
+
+ +

+Definition at line 205 of file include/nel/misc/heap_allocator.h. +

+

00206         { 
+00207                 FreeNodeBlockSize = 128, 
+00208                 FreeNodeBlockSizeShift = 7, 
+00209                 FreeNodeBlockSizeMask = 0x7f 
+00210         };
+
+

+ + + + +
+ + +
anonymous enum [private] +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + + +
Align  +
BlockDataSizeMin  +
+
+ +

+Definition at line 213 of file include/nel/misc/heap_allocator.h. +

+

00214         { 
+00215                 Align = 8,
+00216                 BlockDataSizeMin = 1<<4
+00217         };
+
+

+ + + + +
+ + +
anonymous enum [private] +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + +
UserDataBlockSizeMin  +
+
+ +

+Definition at line 330 of file include/nel/misc/heap_allocator.h. +

+

00331         {
+00332                 UserDataBlockSizeMin = sizeof(CFreeNode)
+00333         };
+
+

+ + + + +
+ + +
anonymous enum +
+
+ + + + + +
+   + + +

+

Enumeration values:
+ + + + + + +
SmallBlockGranularityShift  +
SmallBlockGranularity  +
FirstSmallBlock  +
LastSmallBlock  +
SmallBlockPoolSize  +
+
+ +

+Definition at line 403 of file include/nel/misc/heap_allocator.h. +

+

00404         {
+00405                 // Small block granularity
+00406                 SmallBlockGranularityShift = 3,
+00407 
+00408                 // Small block granularity
+00409                 SmallBlockGranularity = 1<<SmallBlockGranularityShift,
+00410 
+00411                 // Smallest block size
+00412                 FirstSmallBlock = 8,
+00413 
+00414                 // Largest block size
+00415                 LastSmallBlock = 128,
+00416 
+00417                 // Size of a smallblock pool
+00418                 SmallBlockPoolSize = 20
+00419         };
+
+

+ + + + +
+ + +
enum NLMISC::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 85 of file include/nel/misc/heap_allocator.h. +

+

00086         { 
+00088                 Grow, 
+00089 
+00091                 DontGrow 
+00092         };
+
+

+ + + + +
+ + +
enum NLMISC::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 97 of file include/nel/misc/heap_allocator.h. +

+

00098         { 
+00100                 ThrowException, 
+00101 
+00103                 ReturnNull 
+00104         };
+
+


Constructor & Destructor Documentation

+

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

+ +

+Definition at line 71 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), NLMISC::CHeapAllocator::CNullNode::FreeNode, internalAssert, leaveCriticalSection(), NLMISC::CHeapAllocator::CFreeNode::Left, NL_HEAP_NODE_END_SIZE, NL_SMALLBLOCK_COUNT, NLMISC::CHeapAllocator::CFreeNode::Parent, NLMISC::CHeapAllocator::CFreeNode::Right, setNodeBlack(), and uint. +

+

00073 {
+00074         // Critical section
+00075         enterCriticalSection ();
+00076 
+00077         // Allocator name
+00078         _Name[0] = 0;
+00079 
+00080         // Check size of structures must be aligned
+00081         internalAssert ((sizeof (CNodeBegin) & (Align-1)) == 0);
+00082         internalAssert ((NL_HEAP_NODE_END_SIZE & (Align-1)) == 0);
+00083         internalAssert ((sizeof (CFreeNode) & (Align-1)) == 0);
+00084 
+00085         // Check small block sizes
+00086         internalAssert ((FirstSmallBlock&(SmallBlockGranularity-1)) == 0);
+00087         internalAssert ((LastSmallBlock&(SmallBlockGranularity-1)) == 0);
+00088 
+00089         _MainBlockList = NULL;
+00090         _MainBlockSize = mainBlockSize;
+00091         _BlockCount = blockCount;
+00092         _BlockAllocationMode = blockAllocationMode;
+00093         _OutOfMemoryMode = outOfMemoryMode;
+00094         _FreeTreeRoot = &_NullNode.FreeNode;
+00095 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00096         _AlwaysCheck = false;
+00097 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00098 
+00099         _NullNode.FreeNode.Left = &_NullNode.FreeNode;
+00100         _NullNode.FreeNode.Right = &_NullNode.FreeNode;
+00101         _NullNode.FreeNode.Parent = NULL;
+00102 
+00103         setNodeBlack (&_NullNode.FreeNode);
+00104 
+00105 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00106         _AllocateCount = 0;
+00107 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00108 
+00109         // *********************************************************
+00110         // Small Block
+00111         // *********************************************************
+00112 
+00113         // The free smallblock array by size
+00114         const uint smallBlockSizeCount = NL_SMALLBLOCK_COUNT;
+00115         uint smallBlockSize;
+00116         for (smallBlockSize=0; smallBlockSize<smallBlockSizeCount; smallBlockSize++)
+00117         {
+00118                 _FreeSmallBlocks[smallBlockSize] = NULL;
+00119         }
+00120 
+00121         // No small block
+00122         _SmallBlockPool = NULL;
+00123 
+00124         leaveCriticalSection ();
+00125 }
+
+

+ + + + +
+ + + + + + + + + +
NLMISC::CHeapAllocator::~CHeapAllocator  )  [virtual]
+
+ + + + + +
+   + + +

+ +

+Definition at line 129 of file misc/heap_allocator.cpp. +

+References releaseMemory(). +

+

00130 {
+00131         // Release all memory used
+00132         releaseMemory ();
+00133 }
+
+


Member Function Documentation

+

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

+ +

+Definition at line 644 of file misc/heap_allocator.cpp. +

+References buffer, NLMISC::CHeapAllocator::CNodeEnd::EndMarkers, internalAssert, NLMISC::CHeapAllocator::CCategory::Name, NelAlloc, NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, NL_ALIGN_SIZE_FOR_SMALLBLOCK, NL_ALLOC_STOP, NL_HEAP_NODE_END_SIZE, NL_HEAP_SB_CATEGORY, NL_HEAP_UNKNOWN_CATEGORY, NL_SIZE_TO_SMALLBLOCK_INDEX, NL_SMALLBLOCK_COUNT, NL_UPDATE_MAGIC_NUMBER, NLMISC::CHeapAllocator::CMainBlock::Ptr, NLMISC::CHeapAllocator::CMainBlock::Size, NLMISC::CHeapAllocator::CSmallBlockPool::Size, size, NLMISC::CHeapAllocator::CNodeBegin::SizeAndFlags, uint, uint32, and uint8. +

+

00646 {
+00647         // Check size is valid
+00648         if (size != 0)
+00649         {
+00650 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00651                 // If category is NULL
+00652                 if (category == NULL)
+00653                 {
+00654                         // Get the current category
+00655                         CCategory *cat = (CCategory*)_CategoryStack.getPointer ();
+00656                         if (cat)
+00657                         {
+00658                                 category = cat->Name;
+00659                         }
+00660                         else
+00661                         {
+00662                                 // Not yet initialised
+00663                                 category = NL_HEAP_UNKNOWN_CATEGORY;
+00664                         }
+00665                 }
+00666 
+00667                 // Checks ?
+00668                 if (_AlwaysCheck)
+00669                 {
+00670                         // Check heap integrity
+00671                         internalCheckHeap (true);
+00672                 }
+00673 
+00674                 // Check breakpoints
+00675                 /*if (_Breakpoints.find (_AllocateCount) != _Breakpoints.end())
+00676                 {
+00677                         // ********
+00678                         // * STOP *
+00679                         // ********
+00680                         // * Breakpoints allocation
+00681                         // ********
+00682                         NL_ALLOC_STOP;
+00683                 }*/
+00684 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00685 
+00686                 // Small or largs block ?
+00687 #ifdef NLMISC_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
+00688                 if (0)
+00689 #else // NLMISC_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
+00690                 if (size <= LastSmallBlock)
+00691 #endif// NLMISC_HEAP_NO_SMALL_BLOCK_OPTIMIZATION
+00692                 {
+00693                         // *******************
+00694                         // Small block
+00695                         // *******************
+00696                         
+00697                         enterCriticalSectionSB ();
+00698 
+00699                         // Get pointer on the free block list
+00700                         CNodeBegin **freeNode = (CNodeBegin **)_FreeSmallBlocks+NL_SIZE_TO_SMALLBLOCK_INDEX (size);
+00701 
+00702                         // Not found ?
+00703                         if (*freeNode == NULL)
+00704                         {
+00705                                 leaveCriticalSectionSB ();
+00706 
+00707                                 // Size must be aligned
+00708                                 uint alignedSize = NL_ALIGN_SIZE_FOR_SMALLBLOCK (size);
+00709 
+00710                                 // Use internal allocator
+00711                                 CSmallBlockPool *smallBlock = (CSmallBlockPool *)NelAlloc (*this, sizeof(CSmallBlockPool) + SmallBlockPoolSize * (sizeof(CNodeBegin) + alignedSize + 
+00712                                         NL_HEAP_NODE_END_SIZE), NL_HEAP_SB_CATEGORY);
+00713 
+00714                                 enterCriticalSectionSB ();
+00715 
+00716                                 // Link this new block
+00717                                 smallBlock->Size = alignedSize;
+00718                                 smallBlock->Next = (CSmallBlockPool*)_SmallBlockPool;
+00719                                 _SmallBlockPool = smallBlock;
+00720 
+00721                                 // Initialize the block
+00722                                 uint pool;
+00723                                 CNodeBegin *nextNode = *freeNode;
+00724                                 for (pool=0; pool<SmallBlockPoolSize; pool++)
+00725                                 {
+00726                                         // Get the pool
+00727                                         CNodeBegin *node = getSmallBlock (smallBlock, pool);
+00728 
+00729                                         // Set as free
+00730                                         node->SizeAndFlags = alignedSize;
+00731 
+00732                                         // Insert in the list
+00733                                         setNextSmallBlock (node, nextNode);
+00734                                         nextNode = node;
+00735 
+00736                                         // Set debug informations
+00737 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00738                                         // Set node free
+00739                                         setNodeFree (node);
+00740                                         
+00741                                         // End magic number
+00742                                         node->EndMagicNumber = (uint32*)(CNodeEnd*)((uint8*)node + getNodeSize (node) + sizeof (CNodeBegin));
+00743 
+00744                                         // Begin markers
+00745                                         memset (node->BeginMarkers, BeginNodeMarkers, CNodeBegin::MarkerSize-1);
+00746                                         node->BeginMarkers[CNodeBegin::MarkerSize-1] = 0;
+00747 
+00748                                         // End markers
+00749                                         CNodeEnd *endNode = (CNodeEnd*)((uint8*)node + getNodeSize (node) + sizeof (CNodeBegin));
+00750                                         memset (endNode->EndMarkers, EndNodeMarkers, CNodeEnd::MarkerSize-1);
+00751                                         endNode->EndMarkers[CNodeEnd::MarkerSize-1] = 0;
+00752 
+00753                                         // Unallocated memory
+00754                                         memset ((uint8*)node + sizeof(CNodeBegin), UnallocatedMemory, getNodeSize (node) );
+00755 
+00756                                         // No source file
+00757                                         memset (node->Category, 0, CategoryStringLength);
+00758                                         node->File = NULL;
+00759                                         node->Line = 0xffff;
+00760                                         node->AllocateNumber = 0xffffffff;
+00761 
+00762                                         // Heap pointer
+00763                                         node->Heap = this;
+00764 
+00765                                         NL_UPDATE_MAGIC_NUMBER (node);
+00766 
+00767 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00768                                 }
+00769 
+00770                                 // Link the new blocks
+00771                                 *freeNode = nextNode;
+00772                         }
+00773 
+00774                         // Check allocation as been done
+00775                         internalAssert (*freeNode);
+00776 
+00777                         // Get a node
+00778                         CNodeBegin *node = *freeNode;
+00779 
+00780                         // Checks
+00781                         internalAssert (size <= getNodeSize (node));
+00782                         internalAssert ((NL_SIZE_TO_SMALLBLOCK_INDEX (size)) < (NL_SMALLBLOCK_COUNT));
+00783 
+00784                         // Relink
+00785                         *freeNode = getNextSmallBlock (node);
+00786 
+00787 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG           
+00788                         // Check the node CRC
+00789                         checkNode (node, evalMagicNumber (node));
+00790 
+00791                         // Set node free for checks
+00792                         setNodeUsed (node);
+00793 
+00794                         // Fill category
+00795                         strncpy (node->Category, category, CategoryStringLength-1);
+00796 
+00797                         // Source filename
+00798                         node->File = sourceFile;
+00799 
+00800                         // Source line
+00801                         node->Line = line;
+00802 
+00803                         // Allocate count
+00804                         node->AllocateNumber = _AllocateCount++;
+00805 
+00806                         // End magic number aligned on new size
+00807                         node->EndMagicNumber = (uint32*)((uint8*)node + size + sizeof (CNodeBegin));
+00808 
+00809                         // Uninitialised memory
+00810                         memset ((uint8*)node + sizeof(CNodeBegin), UninitializedMemory, (uint32)(node->EndMagicNumber) - ( (uint32)node + sizeof(CNodeBegin) ) );
+00811 
+00812                         // Crc node
+00813                         NL_UPDATE_MAGIC_NUMBER (node);
+00814 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00815 
+00816                         leaveCriticalSectionSB ();
+00817 
+00818                         // Return the user pointer
+00819                         return (void*)((uint)node + sizeof (CNodeBegin));
+00820                 }
+00821                 else
+00822                 {
+00823                         // *******************
+00824                         // Large block
+00825                         // *******************
+00826 
+00827                         // Check size
+00828                         if ( (size & ~CNodeBegin::SizeMask) != 0)
+00829                         {
+00830                                 // ********
+00831                                 // * STOP *
+00832                                 // ********
+00833                                 // * Attempt to allocate more than 1 Go
+00834                                 // ********
+00835                                 NL_ALLOC_STOP;
+00836 
+00837                                 // Select outofmemory mode
+00838                                 if (_OutOfMemoryMode == ReturnNull)
+00839                                         return NULL;
+00840                                 else
+00841                                         throw std::bad_alloc();
+00842                         }
+00843 
+00844                         enterCriticalSectionLB ();
+00845 
+00846                         // Find a free node
+00847                         CHeapAllocator::CFreeNode *freeNode = CHeapAllocator::find (size);
+00848 
+00849                         // The node
+00850                         CNodeBegin *node;
+00851 
+00852                         // Node not found ?
+00853                         if (freeNode == NULL)
+00854                         {
+00855                                 // Block allocation mode
+00856                                 if ((_BlockAllocationMode == DontGrow) && (_MainBlockList != NULL))
+00857                                 {
+00858                                         // Select outofmemory mode
+00859                                         if (_OutOfMemoryMode == ReturnNull)
+00860                                                 return NULL;
+00861                                         else
+00862                                                 throw std::bad_alloc();
+00863                                 }
+00864 
+00865                                 // The node
+00866                                 uint8 *buffer;
+00867 
+00868                                 // Alloc size
+00869                                 uint allocSize;
+00870 
+00871                                 // Aligned size
+00872                                 uint allignedSize = (size&~(Align-1)) + (( (size&(Align-1))==0 ) ? 0 : Align);
+00873                                 if (allignedSize < BlockDataSizeMin)
+00874                                         allignedSize = BlockDataSizeMin;
+00875 
+00876                                 // Does the node bigger than mainNodeSize ?
+00877                                 if (allignedSize > (_MainBlockSize-sizeof (CNodeBegin)-NL_HEAP_NODE_END_SIZE))
+00878                                         // Allocate a specific block
+00879                                         allocSize = allignedSize + sizeof (CNodeBegin) + NL_HEAP_NODE_END_SIZE;
+00880                                 else
+00881                                         // Allocate a new block
+00882                                         allocSize = _MainBlockSize;
+00883 
+00884                                 // Allocate the buffer
+00885                                 buffer = allocateBlock (allocSize+Align);
+00886 
+00887                                 // Add the buffer
+00888                                 CMainBlock *mainBlock = (CMainBlock*)allocateBlock (sizeof(CMainBlock)); 
+00889                                 mainBlock->Size = allocSize+Align;
+00890                                 mainBlock->Ptr = buffer;
+00891                                 mainBlock->Next = _MainBlockList;
+00892                                 _MainBlockList = mainBlock;
+00893 
+00894                                 // Init the new block
+00895                                 initEmptyBlock (*mainBlock);
+00896 
+00897                                 // Get the first node
+00898                                 node = getFirstNode (mainBlock);
+00899                         }
+00900                         else
+00901                         {
+00902                                 // Get the node
+00903                                 node = getNode (freeNode);
+00904 
+00905                                 // Remove the node from free blocks and get the removed block
+00906                                 erase (freeNode);
+00907                         }
+00908 
+00909 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00910                         // Check the node CRC
+00911                         checkNode (node, evalMagicNumber (node));
+00912 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00913 
+00914                         // Split the node
+00915                         CNodeBegin *rest = splitNode (node, size);
+00916 
+00917                         // Fill informations for the first part of the node
+00918 
+00919                         // Clear free flag
+00920                         setNodeUsed (node);
+00921 
+00922 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00923                         // Fill category
+00924                         strncpy (node->Category, category, CategoryStringLength-1);
+00925 
+00926                         // Source filename
+00927                         node->File = sourceFile;
+00928 
+00929                         // Source line
+00930                         node->Line = line;
+00931 
+00932                         // Allocate count
+00933                         node->AllocateNumber = _AllocateCount++;
+00934 
+00935                         // Crc node
+00936                         NL_UPDATE_MAGIC_NUMBER (node);
+00937 
+00938                         // Uninitialised memory
+00939                         memset ((uint8*)node + sizeof(CNodeBegin), UninitializedMemory, (uint32)(node->EndMagicNumber) - ( (uint32)node + sizeof(CNodeBegin) ) );
+00940 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00941 
+00942                         // Node has been splited ?
+00943                         if (rest)
+00944                         {
+00945                                 // Fill informations for the second part of the node
+00946 
+00947                                 // Get the freeNode
+00948                                 freeNode = getFreeNode (rest);
+00949 
+00950                                 // Insert the free node
+00951                                 insert (freeNode);
+00952 
+00953                                 // Crc node
+00954                                 NL_UPDATE_MAGIC_NUMBER (rest);
+00955                         }
+00956 
+00957                         // Check the node size
+00958                         internalAssert ( size <= getNodeSize (node) );
+00959                         internalAssert ( std::max ((uint)BlockDataSizeMin, size + (uint)Align) + sizeof (CNodeBegin) + sizeof (CNodeEnd) + sizeof (CNodeBegin) + sizeof (CNodeEnd) + BlockDataSizeMin >= getNodeSize (node) );
+00960 
+00961                         // Check pointer alignment
+00962                         internalAssert (((uint32)node&(Align-1)) == 0);
+00963                         internalAssert (((uint32)((char*)node + sizeof(CNodeBegin))&(Align-1)) == 0);
+00964 
+00965                         // Check size
+00966                         internalAssert ((uint32)node->EndMagicNumber <= (uint32)((uint8*)node+sizeof(CNodeBegin)+getNodeSize (node) ));
+00967                         internalAssert ((uint32)node->EndMagicNumber > (uint32)(((uint8*)node+sizeof(CNodeBegin)+getNodeSize (node) ) - BlockDataSizeMin - BlockDataSizeMin - sizeof(CNodeBegin) - sizeof(CNodeEnd)));
+00968 
+00969                         leaveCriticalSectionLB ();
+00970 
+00971                         // Return the user pointer
+00972                         return (void*)((uint)node + sizeof (CNodeBegin));
+00973                 }
+00974         }
+00975         else
+00976         {
+00977                 // ********
+00978                 // * STOP *
+00979                 // ********
+00980                 // * Attempt to allocate 0 bytes
+00981                 // ********
+00982                 NL_ALLOC_STOP;
+00983                 return NULL;
+00984         }
+00985 }
+
+

+ + + + +
+ + + + + + + + + + +
uint8 * NLMISC::CHeapAllocator::allocateBlock uint  size  )  [virtual]
+
+ + + + + +
+   + + +

+ +

+Definition at line 2059 of file misc/heap_allocator.cpp. +

+References size, uint, and uint8. +

+

02060 {
+02061 #undef malloc
+02062         return (uint8*)::malloc (size);
+02063 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
bool NLMISC::CHeapAllocator::checkFreeNode const CFreeNode current,
bool  stopOnError,
bool  recurse
const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by internalCheckHeap().

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::checkHeap bool  stopOnError  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 2050 of file misc/heap_allocator.cpp. +

+References internalCheckHeap(), and res. +

+

02051 {
+02052         bool res = internalCheckHeap (stopOnError);
+02053 
+02054         return res;
+02055 }
+
+

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

+ +

+Definition at line 2214 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNodeBegin::EndMagicNumber, NLMISC::CHeapAllocator::CNodeBegin::Heap, NL_ALLOC_STOP, and uint32. +

+Referenced by debugReportMemoryLeak(), free(), getAllocatedMemory(), and getFreeMemory(). +

+

02215 {
+02216         // Check the bottom CRC of the node 
+02217         if (crc != *(node->EndMagicNumber))
+02218         {
+02219                 // ********
+02220                 // * STOP *
+02221                 // ********
+02222                 // * The bottom CRC32 of the current node is wrong. Use checkMemory() to debug the heap.
+02223                 // ********
+02224                 // * (*node) Check for more informations
+02225                 // ********
+02226                 NL_ALLOC_STOP;
+02227         }
+02228 
+02229         // Check the node is hold by this heap
+02230         if (node->Heap != this)
+02231         {
+02232                 // ********
+02233                 // * STOP *
+02234                 // ********
+02235                 // * This node is not hold by this heap. It has been allocated with another heap.
+02236                 // ********
+02237                 // * (*node) Check for more informations
+02238                 // ********
+02239                 NL_ALLOC_STOP;
+02240         }
+02241 }
+
+

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

+ +

+Referenced by internalCheckHeap().

+

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

+ +

+Referenced by internalCheckHeap().

+

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

+

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::debugAlwaysCheckMemory bool  alwaysCheck  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 2143 of file misc/heap_allocator.cpp. +

+

02144 {
+02145         _AlwaysCheck = alwaysCheck;
+02146 }
+
+

+ + + + +
+ + + + + + + + + + +
uint NLMISC::CHeapAllocator::debugGetAllocatedMemoryByCategory const char *  category  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1245 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNodeBegin::Category, enterCriticalSection(), getFirstNode(), getNextNode(), getNodeSize(), getSmallBlock(), isNodeUsed(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, and uint. +

+

01246 {
+01247         enterCriticalSection ();
+01248 
+01249         // Sum allocated memory
+01250         uint memory = 0;
+01251 
+01252         // For each small block
+01253         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01254         while (currentSB)
+01255         {
+01256                 // For each node in this small block pool
+01257                 uint block;
+01258                 for (block=0; block<SmallBlockPoolSize; block++)
+01259                 {
+01260                         // Get the node
+01261                         const CNodeBegin *current = getSmallBlock (currentSB, block);
+01262 
+01263                         // Node allocated ?
+01264                         if ((isNodeUsed (current)) && (strcmp (current->Category, category)==0))
+01265                                 memory += getNodeSize (current);
+01266 
+01267                         memory += getNodeSize (current);
+01268                 }
+01269 
+01270                 // Next block
+01271                 currentSB = currentSB->Next;
+01272         }
+01273 
+01274         // For each main block
+01275         CMainBlock *currentBlock = _MainBlockList;
+01276         while (currentBlock)
+01277         {
+01278                 // Get the first node
+01279                 const CNodeBegin *current = getFirstNode (currentBlock);
+01280                 while (current)
+01281                 {
+01282                         // Node allocated ?
+01283                         if ((isNodeUsed (current)) && (strcmp (current->Category, category)==0))
+01284                                 memory += getNodeSize (current);
+01285 
+01286                         // Next node
+01287                         current = getNextNode (current);
+01288                 }
+01289 
+01290                 // Next block
+01291                 currentBlock = currentBlock->Next;
+01292         }
+01293 
+01294         leaveCriticalSection ();
+01295 
+01296         // Return memory used
+01297         return memory;
+01298 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::debugGetDebugInfoSize  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1304 of file misc/heap_allocator.cpp. +

+References debugGetLBDebugInfoSize(), debugGetSBDebugInfoSize(), and uint. +

+

01305 {
+01306         // Return memory used
+01307         return debugGetSBDebugInfoSize () + debugGetLBDebugInfoSize ();
+01308 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::debugGetLBDebugInfoSize  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1310 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), getFirstNode(), getNextNode(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, and uint. +

+Referenced by debugGetDebugInfoSize(). +

+

01311 {
+01312         enterCriticalSection ();
+01313 
+01314         // Sum memory used by debug header
+01315         uint memory = 0;
+01316 
+01317         // For each main block
+01318         CMainBlock *currentBlock = _MainBlockList;
+01319         while (currentBlock)
+01320         {
+01321                 // Get the first node
+01322                 const CNodeBegin *current = getFirstNode (currentBlock);
+01323                 while (current)
+01324                 {
+01325                         // Node allocated ?
+01326                         memory  += sizeof(CNodeBegin) - ReleaseHeaderSize + sizeof(CNodeEnd);
+01327 
+01328                         // Next node
+01329                         current = getNextNode (current);
+01330                 }
+01331 
+01332                 // Next block
+01333                 currentBlock = currentBlock->Next;
+01334         }
+01335 
+01336         leaveCriticalSection ();
+01337 
+01338         // Return memory used
+01339         return memory;
+01340 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::debugGetSBDebugInfoSize  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1342 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), leaveCriticalSection(), NLMISC::CHeapAllocator::CSmallBlockPool::Next, and uint. +

+Referenced by debugGetDebugInfoSize(). +

+

01343 {
+01344         enterCriticalSection ();
+01345 
+01346         // Sum memory used by debug header
+01347         uint memory = 0;
+01348 
+01349         // For each small blocks
+01350         CSmallBlockPool *pool = (CSmallBlockPool*)_SmallBlockPool;
+01351         while (pool)
+01352         {
+01353                 memory  += SmallBlockPoolSize * (sizeof(CNodeBegin) - ReleaseHeaderSize + sizeof(CNodeEnd));
+01354 
+01355                 // Next pool
+01356                 pool = pool->Next;
+01357         }
+01358 
+01359         leaveCriticalSection ();
+01360 
+01361         // Return memory used
+01362         return memory;
+01363 }
+
+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::debugIsAlwaysCheckMemory bool  alwaysCheck  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 2152 of file misc/heap_allocator.cpp. +

+

02153 {
+02154         return _AlwaysCheck;
+02155 }
+
+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::debugPopCategoryString  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 2189 of file misc/heap_allocator.cpp. +

+References free(), NLMISC::CTDS::getPointer(), NLMISC::CHeapAllocator::CCategory::Next, and NLMISC::CTDS::setPointer(). +

+Referenced by debugReportMemoryLeak(), and debugStatisticsReport(). +

+

02190 {
+02191         // Get the category stack pointer
+02192         CCategory *last = (CCategory*)_CategoryStack.getPointer ();
+02193         // nlassertex (last, ("(CHeapAllocator::debugPopCategoryString ()) Pop category wihtout Push"));
+02194         if (last)
+02195         {
+02196                 CCategory *next = last->Next;
+02197 
+02198                 // Free last node, no need to be thread safe here, because we use thread specifc storage
+02199                 free (last);
+02200 
+02201                 /* Push it, no need to be thread safe here, because we use thread specifc storage */
+02202                 _CategoryStack.setPointer (next);
+02203         }
+02204 }
+
+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::debugPushCategoryString const char *  str  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 2173 of file misc/heap_allocator.cpp. +

+References NLMISC::CTDS::getPointer(), NLMISC::CHeapAllocator::CCategory::Name, NelAlloc, NLMISC::CHeapAllocator::CCategory::Next, NL_HEAP_CATEGORY_BLOCK_CATEGORY, and NLMISC::CTDS::setPointer(). +

+Referenced by debugReportMemoryLeak(), and debugStatisticsReport(). +

+

02174 {
+02175         // Get the category stack pointer
+02176         CCategory *last = (CCategory*)_CategoryStack.getPointer ();
+02177 
+02178         // New category node
+02179         CCategory *_new = (CCategory *)NelAlloc (*this, sizeof(CCategory), NL_HEAP_CATEGORY_BLOCK_CATEGORY);
+02180         _new->Name = str;
+02181         _new->Next = last;
+02182 
+02183         /* Push it, no need to be thread safe here, because we use thread specifc storage */
+02184         _CategoryStack.setPointer (_new);
+02185 }
+
+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::debugReportMemoryLeak  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 1916 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocatorOutputError(), checkNode(), debugPopCategoryString(), debugPushCategoryString(), getFirstNode(), getNextNode(), getNodeSize(), getSmallBlock(), isNodeUsed(), NLMISC::CHeapAllocator::CSmallBlockPool::Next, NLMISC::CHeapAllocator::CMainBlock::Next, NL_HEAP_MEM_DEBUG_CATEGORY, NLMISC::report(), NLMISC::smprintf(), NLMISC::TLinkMap, and uint. +

+

01917 {
+01918         // enterCriticalSection ();
+01919 
+01920         debugPushCategoryString (NL_HEAP_MEM_DEBUG_CATEGORY);
+01921 
+01922         // Sum allocated memory
+01923         uint memory = 0;
+01924 
+01925         // Leak map
+01926         TLinkMap leakMap;
+01927 
+01928         // Header
+01929         char report[2048];
+01930         smprintf (report, 2048, "Report Memory leak for allocator \"%s\"\n", _Name);
+01931         CHeapAllocatorOutputError (report);
+01932 
+01933         // For each small block
+01934         CMainBlock *currentBlock = _MainBlockList;
+01935         while (currentBlock)
+01936         {
+01937                 // Get the first node
+01938                 const CNodeBegin *current = getFirstNode (currentBlock);
+01939                 while (current)
+01940                 {
+01941                         // Check node
+01942                         checkNode (current, evalMagicNumber (current));
+01943 
+01944                         // Node allocated ?
+01945                         if (isNodeUsed (current) && ( (current->Category == NULL) || (current->Category[0] != '_')) )
+01946                         {
+01947                                 // Make a report
+01948                                 smprintf (report, 2048, "%s(%d)\t: \"%s\"", current->File, current->Line, current->Category);
+01949 
+01950                                 // Look for this leak
+01951                                 TLinkMap::iterator ite = leakMap.find (report);
+01952 
+01953                                 // Not found ?
+01954                                 if (ite == leakMap.end ())
+01955                                 {
+01956                                         ite = leakMap.insert (TLinkMap::value_type (report, CLeak ())).first;
+01957                                         ite->second.Count = 0;
+01958                                         ite->second.Memory = 0;
+01959                                 }
+01960 
+01961                                 // One more leak
+01962                                 ite->second.Count++;
+01963                                 ite->second.Memory += getNodeSize (current);
+01964 
+01965                                 memory += getNodeSize (current);
+01966                         }
+01967 
+01968                         // Next node
+01969                         current = getNextNode (current);
+01970                 }
+01971 
+01972                 // Next block
+01973                 currentBlock = currentBlock->Next;
+01974         }
+01975 
+01976         // For each small block
+01977         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01978         while (currentSB)
+01979         {
+01980                 // For each node in this small block pool
+01981                 uint block;
+01982                 for (block=0; block<SmallBlockPoolSize; block++)
+01983                 {
+01984                         // Get the node
+01985                         const CNodeBegin *current = getSmallBlock (currentSB, block);
+01986                         // Check node
+01987                         checkNode (current, evalMagicNumber (current));
+01988 
+01989                         // Node allocated ?
+01990                         if (isNodeUsed (current) && ( (current->Category == NULL) || (current->Category[0] != '_')) )
+01991                         {
+01992                                 // Make a report
+01993                                 smprintf (report, 2048, "%s(%d)\t: \"%s\"",     current->File, current->Line, current->Category);
+01994 
+01995                                 // Look for this leak
+01996                                 TLinkMap::iterator ite = leakMap.find (report);
+01997 
+01998                                 // Not found ?
+01999                                 if (ite == leakMap.end ())
+02000                                 {
+02001                                         ite = leakMap.insert (TLinkMap::value_type (report, CLeak ())).first;
+02002                                         ite->second.Count = 0;
+02003                                         ite->second.Memory = 0;
+02004                                 }
+02005 
+02006                                 // One more leak
+02007                                 ite->second.Count++;
+02008                                 ite->second.Memory += getNodeSize (current);
+02009 
+02010                                 memory += getNodeSize (current);
+02011                         }
+02012                 }
+02013 
+02014                 // Next block
+02015                 currentSB = currentSB->Next;
+02016         }
+02017 
+02018         // Look for this leak
+02019         TLinkMap::iterator ite = leakMap.begin ();
+02020         while (ite != leakMap.end ())
+02021         {
+02022                 // Make a report
+02023                 smprintf (report, 2048, "%s,\tLeak count : %d,\tMemory allocated : %d\n", ite->first.c_str (), ite->second.Count, ite->second.Memory);
+02024 
+02025                 // Report on stderr
+02026                 CHeapAllocatorOutputError (report);
+02027 
+02028                 ite++;
+02029         }
+02030 
+02031         // Make a report
+02032         if (memory)
+02033         {
+02034                 smprintf (report, 2048, "%d byte(s) found\n", memory);
+02035         }
+02036         else
+02037         {
+02038                 smprintf (report, 2048, "No memory leak\n");
+02039         }
+02040         CHeapAllocatorOutputError (report);
+02041 
+02042         debugPopCategoryString ();
+02043 
+02044         // leaveCriticalSection ();
+02045 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
bool NLMISC::CHeapAllocator::debugStatisticsReport const char *  stateFile,
bool  memoryMap
+
+ + + + + +
+   + + +

+ +

+Definition at line 1393 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNodeBegin::Category, count, debugPopCategoryString(), debugPushCategoryString(), file, getAllocatedSystemMemory(), getAllocatedSystemMemoryByAllocator(), getFirstNode(), getNextNode(), getNodeSize(), getSmallBlock(), index, isNodeFree(), isNodeUsed(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, NL_HEAP_MEM_DEBUG_CATEGORY, NL_HEAP_NODE_END_SIZE, NL_SIZE_TO_SMALLBLOCK_INDEX, NL_SMALLBLOCK_COUNT, NLMISC::CHeapAllocator::CSmallBlockPool::Size, size, and uint. +

+

01394 {
+01395         // Status
+01396         bool status = false;
+01397 
+01398         debugPushCategoryString (NL_HEAP_MEM_DEBUG_CATEGORY);
+01399 
+01400         // Open files
+01401         FILE *file = fopen (stateFile, "wt");
+01402 
+01403         // Block map
+01404         typedef std::map<std::string, CCategoryMap> TBlockMap;
+01405         TBlockMap blockMap;
+01406 
+01407         // Both OK
+01408         if (file)
+01409         {
+01410                 // **************************
+01411 
+01412                 // For each small block
+01413                 uint smallBlockCount = 0;
+01414                 uint largeBlockCount = 0;
+01415                 CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01416                 while (currentSB)
+01417                 {
+01418                         // For each node in this small block pool
+01419                         uint block;
+01420                         for (block=0; block<SmallBlockPoolSize; block++)
+01421                         {
+01422                                 // Get the node
+01423                                 const CNodeBegin *current = getSmallBlock (currentSB, block);
+01424 
+01425                                 // Node allocated ?
+01426                                 if (isNodeUsed (current))
+01427                                 {
+01428                                         // Find the node
+01429                                         TBlockMap::iterator ite = blockMap.find ((const char*)current->Category);
+01430 
+01431                                         // Found ?
+01432                                         if (ite == blockMap.end ())
+01433                                         {
+01434                                                 ite = blockMap.insert (TBlockMap::value_type (current->Category, CCategoryMap ())).first;
+01435                                         }
+01436                                         uint size = getNodeSize (current) + ReleaseHeaderSize;
+01437                                         ite->second.BlockCount++;
+01438                                         ite->second.Size += size;
+01439                                         if (size < ite->second.Min)
+01440                                                 ite->second.Min = size;
+01441                                         if (size > ite->second.Max)
+01442                                                 ite->second.Max = size;
+01443                                 }
+01444 
+01445                                 // Next node
+01446                                 smallBlockCount++;
+01447                         }
+01448 
+01449                         // Next block
+01450                         currentSB = currentSB->Next;
+01451                 }
+01452 
+01453                 // For each main block
+01454                 CMainBlock *currentBlock = _MainBlockList;
+01455                 while (currentBlock)
+01456                 {
+01457                         // Get the first node
+01458                         const CNodeBegin *current = getFirstNode (currentBlock);
+01459                         while (current)
+01460                         {
+01461                                 // Node is used ?
+01462                                 if (isNodeUsed (current))
+01463                                 {
+01464                                         // Find the node
+01465                                         TBlockMap::iterator ite = blockMap.find ((const char*)current->Category);
+01466 
+01467                                         // Found ?
+01468                                         if (ite == blockMap.end ())
+01469                                         {
+01470                                                 ite = blockMap.insert (TBlockMap::value_type (current->Category, CCategoryMap ())).first;
+01471                                         }
+01472                                         uint size = getNodeSize (current) + ReleaseHeaderSize;
+01473                                         ite->second.BlockCount++;
+01474                                         ite->second.Size += size;
+01475                                         if (size < ite->second.Min)
+01476                                                 ite->second.Min = size;
+01477                                         if (size > ite->second.Max)
+01478                                                 ite->second.Max = size;
+01479                                 }
+01480 
+01481                                 // Next node
+01482                                 current = getNextNode (current);
+01483                                 largeBlockCount++;
+01484                         }
+01485 
+01486                         // Next block
+01487                         currentBlock = currentBlock->Next;
+01488                 }
+01489 
+01490                 // Write the heap info file
+01491                 fprintf (file, "HEAP STATISTICS\n");
+01492                 fprintf (file, "HEAP, TOTAL MEMORY USED, ALLOCATED MEMORY, FREE MEMORY, FRAGMENTATION RATIO, MAIN BLOCK SIZE, MAIN BLOCK COUNT\n");
+01493 
+01494                 fprintf (file, "%s, %d, %d, %d, %f%%, %d, %d\n", _Name, getTotalMemoryUsed (),
+01495                         getAllocatedMemory (), getFreeMemory (), 100.f*getFragmentationRatio (), getMainBlockSize (), getMainBlockCount ());
+01496 
+01497                 fprintf (file, "\n\nHEAP BLOCKS\n");
+01498                 fprintf (file, "SMALL BLOCK MEMORY, SMALL BLOCK COUNT, LARGE BLOCK COUNT\n");
+01499 
+01500                 fprintf (file, "%d, %d, %d\n", getSmallBlockMemory (), smallBlockCount, largeBlockCount);
+01501 
+01502                 fprintf (file, "\n\nHEAP DEBUG INFOS\n");
+01503                 fprintf (file, "SB DEBUG INFO, LB DEBUG INFO, TOTAL DEBUG INFO\n");
+01504 
+01505                 fprintf (file, "%d, %d, %d\n", debugGetSBDebugInfoSize (), debugGetLBDebugInfoSize (), debugGetDebugInfoSize ());
+01506 
+01507                 // **************************
+01508 
+01509                 // Write the system heap info file
+01510                 uint systemMemory = getAllocatedSystemMemory ();
+01511                 uint nelSystemMemory = getAllocatedSystemMemoryByAllocator ();
+01512 
+01513                 fprintf (file, "\n\nSYSTEM HEAP STATISTICS\n");
+01514                 fprintf (file, "TOTAL ALLOCATED MEMORY, NEL ALLOCATED MEMORY, OTHER ALLOCATED MEMORY\n");
+01515                 fprintf (file, "%d, %d, %d\n", systemMemory, nelSystemMemory, systemMemory-nelSystemMemory);
+01516 
+01517                 // Write the category map file
+01518                 fprintf (file, "\n\n\nCATEGORY STATISTICS\n");
+01519                 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");
+01520 
+01521                 TBlockMap::iterator ite = blockMap.begin();
+01522                 while (ite != blockMap.end())
+01523                 {
+01524                         // Number of small blocks
+01525                         uint smallB[NL_SMALLBLOCK_COUNT];
+01526 
+01527                         // Clean
+01528                         uint smallBlock;
+01529                         for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
+01530                         {
+01531                                 smallB[smallBlock] = 0;
+01532                         }
+01533                         
+01534                         // Scan small block for this category
+01535                         currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01536                         while (currentSB)
+01537                         {
+01538                                 // For each node in this small block pool
+01539                                 uint block;
+01540                                 for (block=0; block<SmallBlockPoolSize; block++)
+01541                                 {
+01542                                         // Get the node
+01543                                         const CNodeBegin *current = getSmallBlock (currentSB, block);
+01544 
+01545                                         // Node allocated ?
+01546                                         if (isNodeUsed (current))
+01547                                         {
+01548                                                 // Good node ?
+01549                                                 if (current->Category == ite->first)
+01550                                                 {
+01551                                                         // Get the small block index
+01552                                                         uint index = NL_SIZE_TO_SMALLBLOCK_INDEX (getNodeSize (current));
+01553 
+01554                                                         // One more node
+01555                                                         smallB[index]++;
+01556                                                 }
+01557                                         }
+01558                                 }
+01559 
+01560                                 // Next block
+01561                                 currentSB = currentSB->Next;
+01562                         }
+01563 
+01564                         // Average
+01565                         uint average = ite->second.Size / ite->second.BlockCount;
+01566 
+01567                         // Print the line
+01568                         fprintf (file, "%s, %d, %d, %d, %d, %d", ite->first.c_str(), ite->second.BlockCount, ite->second.Size, 
+01569                                 ite->second.Min, ite->second.Max, average);
+01570 
+01571                         // Print small blocks
+01572                         for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
+01573                         {
+01574                                 fprintf (file, ", %d", smallB[smallBlock]);
+01575                         }
+01576 
+01577                         fprintf (file, "\n");
+01578 
+01579                         ite++;
+01580                 }
+01581 
+01582                 // **************************
+01583 
+01584                 // Write the small block statistics
+01585                 fprintf (file, "\n\n\nSMALL BLOCK STATISTICS\n");
+01586                 fprintf (file, "SIZE, BLOCK COUNT, BLOCK FREE, BLOCK USED, TOTAL MEMORY USED\n");
+01587 
+01588                 // Number of small blocks
+01589                 uint count[NL_SMALLBLOCK_COUNT];
+01590                 uint free[NL_SMALLBLOCK_COUNT];
+01591 
+01592                 uint smallBlock;
+01593                 for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
+01594                 {
+01595                         count[smallBlock] = 0;
+01596                         free[smallBlock] = 0;
+01597                 }
+01598 
+01599                 // For each small block
+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                                 // Get the small block index
+01611                                 uint index = NL_SIZE_TO_SMALLBLOCK_INDEX (getNodeSize (current));
+01612 
+01613                                 // Add a block
+01614                                 count[index]++;
+01615 
+01616                                 // Node allocated ?
+01617                                 if (isNodeFree (current))
+01618                                 {
+01619                                         // Add a free block
+01620                                         free[index]++;
+01621                                 }
+01622 
+01623                                 // Next node
+01624                                 current = getNextNode (current);
+01625                         }
+01626 
+01627                         // Next block
+01628                         currentSB = currentSB->Next;
+01629                 }
+01630 
+01631                 // Print stats
+01632                 for (smallBlock=0; smallBlock<NL_SMALLBLOCK_COUNT; smallBlock++)
+01633                 {
+01634                         uint size = (smallBlock+1)*SmallBlockGranularity;
+01635                         fprintf (file,"%d, %d, %d, %d, %d\n",size, count[smallBlock], free[smallBlock], 
+01636                                 count[smallBlock]-free[smallBlock], count[smallBlock]*(sizeof (CNodeBegin) + size + NL_HEAP_NODE_END_SIZE));
+01637                 }
+01638                 
+01639                 // **************************
+01640 
+01641                 // Write the memory map file
+01642                 if (memoryMap)
+01643                 {
+01644                         fprintf (file, "\n\n\nHEAP LARGE BLOCK DUMP\n");
+01645                         fprintf (file, "ADDRESS, SIZE, CATEGORY, HEAP, STATE, SOURCE, LINE\n");
+01646 
+01647                         // For each main block
+01648                         currentBlock = _MainBlockList;
+01649                         while (currentBlock)
+01650                         {
+01651                                 // Get the first node
+01652                                 const CNodeBegin *current = getFirstNode (currentBlock);
+01653                                 while (current)
+01654                                 {
+01655                                         // Write the entry
+01656                                         fprintf (file, "0x%08x, %d, %s, %s, %s, %s, %d\n", (uint)current + sizeof(CNodeBegin),
+01657                                                 getNodeSize (current), current->Category, _Name, 
+01658                                                 isNodeFree (current)?"free":"used", current->File, current->Line);
+01659 
+01660                                         // Next node
+01661                                         current = getNextNode (current);
+01662                                 }
+01663 
+01664                                 // Next block
+01665                                 currentBlock = currentBlock->Next;
+01666                         }
+01667                 }
+01668 
+01669                 // File created successfuly
+01670                 status = true;
+01671         }
+01672 
+01673         // Close
+01674         if (file)
+01675                 fclose (file);
+01676 
+01677         debugPopCategoryString ();
+01678 
+01679         return status;
+01680 }
+
+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::enterCriticalSection  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by CHeapAllocator(), debugGetAllocatedMemoryByCategory(), debugGetLBDebugInfoSize(), debugGetSBDebugInfoSize(), freeAll(), getAllocatedMemory(), getFragmentationRatio(), getFreeMemory(), getSmallBlockMemory(), getTotalMemoryUsed(), internalCheckHeap(), releaseMemory(), and setName().

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::enterCriticalSectionLB  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by free().

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::enterCriticalSectionSB  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by free().

+

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

+ +

+Definition at line 260 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNullNode::FreeNode, internalAssert, isNodeBlack(), isNodeRed(), NL_UPDATE_MAGIC_NUMBER_FREE_NODE, rotateLeft(), rotateRight(), setNodeBlack(), setNodeColor(), setNodeRed(), w, x, y, and z. +

+Referenced by free(). +

+

00261 {
+00262         CFreeNode *x, *y;
+00263         if (z->Left == &_NullNode.FreeNode || z->Right == &_NullNode.FreeNode)
+00264         {
+00265                 // y has a NULL node as a child
+00266                 y = z;
+00267         }
+00268         else
+00269         {
+00270                 // Find tree successor with a &_NullNode.FreeNode node as a child
+00271                 y = z->Right;
+00272                 while (y->Left != &_NullNode.FreeNode)
+00273                         y = y->Left;
+00274         }
+00275         
+00276         // x is y's only child
+00277         if (y->Left != &_NullNode.FreeNode)
+00278                 x = y->Left;
+00279         else
+00280                 x = y->Right;
+00281 
+00282         // Remove y from the parent chain
+00283         x->Parent = y->Parent;
+00284 
+00285         if (y->Parent)
+00286         {
+00287                 if (y == y->Parent->Left)
+00288                         y->Parent->Left = x;
+00289                 else
+00290                 {
+00291                         internalAssert (y == y->Parent->Right);
+00292                         y->Parent->Right = x;
+00293                 }
+00294                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Parent);
+00295         }
+00296         else
+00297                 _FreeTreeRoot = x;
+00298 
+00299         bool yRed = isNodeRed (y);
+00300 
+00301         if (y != z)
+00302         {
+00303                 // Replace y by z
+00304                 *y = *z;
+00305                 setNodeColor (y, isNodeRed (z));
+00306                 if (y->Parent)
+00307                 {
+00308                         if (y->Parent->Left == z)
+00309                         {
+00310                                 y->Parent->Left = y;
+00311                         }
+00312                         else
+00313                         {
+00314                                 internalAssert (y->Parent->Right == z);
+00315                                 y->Parent->Right = y;
+00316                         }
+00317                 }
+00318                 else
+00319                 {
+00320                         internalAssert (_FreeTreeRoot == z);
+00321                         _FreeTreeRoot = y;
+00322                 }
+00323 
+00324                 if (y->Left)
+00325                 {
+00326                         internalAssert (y->Left->Parent == z);
+00327                         y->Left->Parent = y;
+00328                         
+00329                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Left);
+00330                 }
+00331                 if (y->Right)
+00332                 {
+00333                         internalAssert (y->Right->Parent == z);
+00334                         y->Right->Parent = y;
+00335         
+00336                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Right);
+00337                 }
+00338         }
+00339 
+00340         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x);
+00341         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y);
+00342         if (y->Parent)
+00343                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y->Parent);
+00344 
+00345         if (!yRed)
+00346         {
+00347                 // Maintain Red-Black tree balance
+00348                 // After deleting node x
+00349                 while (x != _FreeTreeRoot && isNodeBlack (x))
+00350                 {
+00351                         if (x == x->Parent->Left)
+00352                         {
+00353                                 CFreeNode *w = x->Parent->Right;
+00354                                 if (isNodeRed (w))
+00355                                 {
+00356                                         setNodeBlack (w);
+00357                                         setNodeRed (x->Parent);
+00358                                         rotateLeft (x->Parent);
+00359 
+00360                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00361 
+00362                                         w = x->Parent->Right;
+00363                                 }
+00364                                 if (isNodeBlack (w->Left) && isNodeBlack (w->Right))
+00365                                 {
+00366                                         setNodeRed (w);
+00367                                         x = x->Parent;
+00368 
+00369                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00370                                 }
+00371                                 else
+00372                                 {
+00373                                         if (isNodeBlack (w->Right))
+00374                                         {
+00375                                                 setNodeBlack (w->Left);
+00376                                                 setNodeRed (w);
+00377                                                 rotateRight (w);
+00378                                                 w = x->Parent->Right;
+00379                                         }
+00380                                         setNodeColor (w, isNodeRed (x->Parent));
+00381                                         setNodeBlack (x->Parent);
+00382                                         setNodeBlack (w->Right);
+00383                                         rotateLeft (x->Parent);
+00384 
+00385                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00386                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w->Right);
+00387 
+00388                                         x = _FreeTreeRoot;
+00389                                 }
+00390                         }
+00391                         else
+00392                         {
+00393                                 CFreeNode *w = x->Parent->Left;
+00394                                 if (isNodeRed (w))
+00395                                 {
+00396                                         setNodeBlack (w);
+00397                                         setNodeRed (x->Parent);
+00398                                         rotateRight (x->Parent);
+00399 
+00400                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00401 
+00402                                         w = x->Parent->Left;
+00403                                 }
+00404                                 if ( isNodeBlack (w->Right) && isNodeBlack (w->Left) )
+00405                                 {
+00406                                         setNodeRed (w);
+00407                                         x = x->Parent;
+00408 
+00409                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00410                                 }
+00411                                 else
+00412                                 {
+00413                                         if ( isNodeBlack (w->Left) )
+00414                                         {
+00415                                                 setNodeBlack (w->Right);
+00416                                                 setNodeRed (w);
+00417                                                 rotateLeft (w);
+00418                                                 w = x->Parent->Left;
+00419                                         }
+00420                                         setNodeColor (w, isNodeRed (x->Parent) );
+00421                                         setNodeBlack (x->Parent);
+00422                                         setNodeBlack (w->Left);
+00423 
+00424                                         rotateRight (x->Parent);
+00425 
+00426                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w);
+00427                                         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (w->Left);
+00428 
+00429                                         x = _FreeTreeRoot;
+00430                                 }
+00431                         }
+00432                 }
+00433                 setNodeBlack (x);
+00434                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x);
+00435         }
+00436 }
+
+

+ + + + +
+ + + + + + + + + + +
uint32 NLMISC::CHeapAllocator::evalMagicNumber const CNodeBegin node  )  [static, private]
+
+ + + + + +
+   + + +

+

+

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

+

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::free void *  ptr  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 989 of file misc/heap_allocator.cpp. +

+References checkNode(), NLMISC::CHeapAllocator::CNodeBegin::EndMagicNumber, enterCriticalSectionLB(), enterCriticalSectionSB(), erase(), getNextNode(), getNodeSize(), insert(), internalCheckHeap(), isNodeFree(), leaveCriticalSectionLB(), leaveCriticalSectionSB(), mergeNode(), NL_ALLOC_STOP, NL_SIZE_TO_SMALLBLOCK_INDEX, NL_UPDATE_MAGIC_NUMBER, NLMISC::CHeapAllocator::CNodeBegin::Previous, setNodeFree(), size, uint, uint32, and uint8. +

+Referenced by debugPopCategoryString(). +

+

00990 {
+00991         // Delete a null pointer ?
+00992         if (ptr == NULL)
+00993         {
+00994                 // ********
+00995                 // * STOP *
+00996                 // ********
+00997                 // * Attempt to delete a NULL pointer
+00998                 // ********
+00999 #ifdef NLMISC_HEAP_STOP_NULL_FREE
+01000                 NL_ALLOC_STOP;
+01001 #endif // NLMISC_HEAP_STOP_NULL_FREE
+01002         }
+01003         else
+01004         {
+01005 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01006                 // Checks ?
+01007                 if (_AlwaysCheck)
+01008                 {
+01009                         // Check heap integrity
+01010                         internalCheckHeap (true);
+01011                 }
+01012 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01013                 
+01014                 // Get the node pointer
+01015                 CNodeBegin *node = (CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin));
+01016 
+01017 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01018                 // Check the node CRC
+01019                 enterCriticalSectionSB ();
+01020                 enterCriticalSectionLB ();
+01021                 checkNode (node, evalMagicNumber (node));
+01022                 leaveCriticalSectionLB ();
+01023                 leaveCriticalSectionSB ();
+01024 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01025 
+01026                 // Large or small block ?
+01027 #ifdef NLMISC_HEAP_ALLOCATION_NDEBUG
+01028                 uint size = (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))))->SizeAndFlags;
+01029 #else // NLMISC_HEAP_ALLOCATION_NDEBUG
+01030                 uint size = getNodeSize (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))));
+01031 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01032                 if (size <= LastSmallBlock)
+01033                 {
+01034                         // *******************
+01035                         // Small block
+01036                         // *******************
+01037 
+01038                         // Check the node has not been deleted
+01039                         if (isNodeFree (node))
+01040                         {
+01041                                 // ********
+01042                                 // * STOP *
+01043                                 // ********
+01044                                 // * Attempt to delete a pointer already deleted
+01045                                 // ********
+01046                                 // * (*node):   the already deleted node
+01047                                 // ********
+01048                                 NL_ALLOC_STOP;
+01049                         }
+01050                         else
+01051                         {
+01052                                 enterCriticalSectionSB ();
+01053 
+01054 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01055                                 // Uninitialised memory
+01056                                 memset ((uint8*)node + sizeof(CNodeBegin), DeletedMemory, size );
+01057 
+01058                                 // Set end pointers
+01059                                 node->EndMagicNumber = (uint32*)((uint8*)node + size + sizeof (CNodeBegin));
+01060 
+01061                                 // Mark has free
+01062                                 setNodeFree (node);
+01063 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01064 
+01065                                 // Add in the free list
+01066                                 CNodeBegin **freeNode = (CNodeBegin **)_FreeSmallBlocks+NL_SIZE_TO_SMALLBLOCK_INDEX (size);
+01067                                 ((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin)))->Previous = *freeNode;
+01068                                 *freeNode = ((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin)));
+01069 
+01070                                 // Update smallblock crc
+01071                                 NL_UPDATE_MAGIC_NUMBER (node);
+01072 
+01073                                 leaveCriticalSectionSB ();
+01074                         }
+01075                 }
+01076                 else
+01077                 {
+01078 #ifdef NLMISC_HEAP_ALLOCATION_NDEBUG
+01079                         // Get the real size
+01080                         size = getNodeSize (((CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin))));
+01081 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01082 
+01083                         // Get the node pointer
+01084                         CNodeBegin *node = (CNodeBegin*) ((uint)ptr - sizeof (CNodeBegin));
+01085 
+01086                         // Check the node has not been deleted
+01087                         if (isNodeFree (node))
+01088                         {
+01089                                 // ********
+01090                                 // * STOP *
+01091                                 // ********
+01092                                 // * Attempt to delete a pointer already deleted
+01093                                 // ********
+01094                                 // * (*node):   the already deleted node
+01095                                 // ********
+01096                                 NL_ALLOC_STOP;
+01097                         }
+01098                         else
+01099                         {
+01100                                 enterCriticalSectionLB ();
+01101 
+01102 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01103                                 // Uninitialised memory
+01104                                 memset ((uint8*)node + sizeof(CNodeBegin), DeletedMemory, size );
+01105 
+01106                                 // Set end pointers
+01107                                 node->EndMagicNumber = (uint32*)((uint8*)node + size + sizeof (CNodeBegin));
+01108 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01109 
+01110                                 // Mark has free
+01111                                 setNodeFree (node);
+01112 
+01113                                 // *******************
+01114                                 // Large block
+01115                                 // *******************
+01116 
+01117                                 // A free node
+01118                                 //CHeapAllocator::CFreeNode *freeNode = NULL;
+01119 
+01120                                 // Previous node
+01121                                 CNodeBegin *previous = node->Previous;
+01122                                 if (previous)
+01123                                 {
+01124 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01125                                         // Check the previous node
+01126                                         checkNode (previous, evalMagicNumber (previous));
+01127 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01128 
+01129                                         // Is it free ?
+01130                                         if (isNodeFree (previous))
+01131                                         {
+01132                                                 // Merge the two nodes
+01133                                                 mergeNode (node);
+01134 
+01135                                                 // Get its free node
+01136                                                 erase (getFreeNode (previous));
+01137 
+01138                                                 // Curent node
+01139                                                 node = previous;
+01140                                         }
+01141                                 }
+01142 
+01143                                 // Mark has free
+01144                                 setNodeFree (node);
+01145 
+01146                                 // Next node
+01147                                 CNodeBegin *next = getNextNode (node);
+01148                                 if (next)
+01149                                 {
+01150 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01151                                         // Check the next node
+01152                                         checkNode (next, evalMagicNumber (next));
+01153 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01154 
+01155                                         // Is it free ?
+01156                                         if (isNodeFree (next))
+01157                                         {
+01158                                                 // Free the new one
+01159                                                 erase (getFreeNode (next));
+01160 
+01161                                                 // Merge the two nodes
+01162                                                 mergeNode (next);
+01163                                         }
+01164                                 }
+01165 
+01166                                 // Insert it into the tree
+01167                                 insert (getFreeNode (node));
+01168 
+01169                                 NL_UPDATE_MAGIC_NUMBER (node);
+01170                                 
+01171                                 leaveCriticalSectionLB ();
+01172                         }
+01173                 }
+01174         }
+01175 }
+
+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::freeAll  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 1845 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), NLMISC::CHeapAllocator::CNullNode::FreeNode, getFirstNode(), initEmptyBlock(), insert(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, and NL_UPDATE_MAGIC_NUMBER. +

+

01846 {
+01847         enterCriticalSection ();
+01848 
+01849         // Sum free memory
+01850         //uint memory = 0;
+01851 
+01852         // Clear the free tree
+01853         _FreeTreeRoot = &_NullNode.FreeNode;
+01854 
+01855         // For each main block
+01856         CMainBlock *currentBlock = _MainBlockList;
+01857         while (currentBlock)
+01858         {
+01859                 // Reinit this block
+01860                 initEmptyBlock (*currentBlock);
+01861 
+01862                 // Get first block
+01863                 CNodeBegin *node = getFirstNode (currentBlock);
+01864 
+01865                 // Insert the free node
+01866                 insert (getFreeNode (node));
+01867 
+01868                 NL_UPDATE_MAGIC_NUMBER (node);
+01869 
+01870                 // Next block
+01871                 currentBlock = currentBlock->Next;
+01872         }
+01873 
+01874         leaveCriticalSection ();
+01875 }
+
+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::freeBlock uint8 block  )  [virtual]
+
+ + + + + +
+   + + +

+ +

+Definition at line 2067 of file misc/heap_allocator.cpp. +

+References uint8. +

+Referenced by releaseMemory(). +

+

02068 {
+02069         ::free (block);
+02070 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getAllocatedMemory  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1181 of file misc/heap_allocator.cpp. +

+References checkNode(), enterCriticalSection(), getFirstNode(), getNextNode(), getNodeSize(), getSmallBlock(), isNodeUsed(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, NL_HEAP_SB_CATEGORY, and uint. +

+

01182 {
+01183         enterCriticalSection ();
+01184 
+01185         // Sum allocated memory
+01186         uint memory = 0;
+01187 
+01188         // For each small block
+01189         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01190         while (currentSB)
+01191         {
+01192                 // For each node in this small block pool
+01193                 uint block;
+01194                 for (block=0; block<SmallBlockPoolSize; block++)
+01195                 {
+01196                         // Get the node
+01197                         const CNodeBegin *current = getSmallBlock (currentSB, block);
+01198 
+01199                         // Node allocated ?
+01200                         if (isNodeUsed (current))
+01201                                 memory += getNodeSize (current) + ReleaseHeaderSize;
+01202                 }
+01203 
+01204                 // Next block
+01205                 currentSB = currentSB->Next;
+01206         }
+01207 
+01208         // For each main block
+01209         CMainBlock *currentBlock = _MainBlockList;
+01210         while (currentBlock)
+01211         {
+01212                 // Get the first node
+01213                 const CNodeBegin *current = getFirstNode (currentBlock);
+01214                 while (current)
+01215                 {
+01216 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01217                         // Check node
+01218                         checkNode (current, evalMagicNumber (current));
+01219 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01220 
+01221                         // Node allocated ? Don't sum small blocks..
+01222                         if (isNodeUsed (current))
+01223 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01224                                 if (strcmp (current->Category, NL_HEAP_SB_CATEGORY) != 0)
+01225 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01226                                         memory += getNodeSize (current) + ReleaseHeaderSize;
+01227 
+01228                         // Next node
+01229                         current = getNextNode (current);
+01230                 }
+01231 
+01232                 // Next block
+01233                 currentBlock = currentBlock->Next;
+01234         }
+01235 
+01236         leaveCriticalSection ();
+01237 
+01238         // Return memory used
+01239         return memory;
+01240 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getAllocatedSystemMemory  )  [static]
+
+ + + + + +
+   + + +

+ +

+Definition at line 2269 of file misc/heap_allocator.cpp. +

+References buffer, len, nlwarning, NLMISC::skipToken(), NLMISC::skipWS(), and uint. +

+Referenced by debugStatisticsReport(). +

+

02270 {
+02271         uint systemMemory = 0;
+02272 #ifdef NL_OS_WINDOWS
+02273         // Get system memory informations
+02274         HANDLE hHeap[100];
+02275         DWORD heapCount = GetProcessHeaps (100, hHeap);
+02276 
+02277         uint heap;
+02278         for (heap = 0; heap < heapCount; heap++)
+02279         {
+02280                 PROCESS_HEAP_ENTRY entry;
+02281                 entry.lpData = NULL;
+02282                 while (HeapWalk (hHeap[heap], &entry))
+02283                 {
+02284                         if (entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
+02285                         {
+02286                                 systemMemory += entry.cbData + entry.cbOverhead;
+02287                         }
+02288                 }
+02289         }
+02290 
+02291 #elif defined NL_OS_UNIX
+02292         
+02293         int fd = open("/proc/self/stat", O_RDONLY);
+02294         if (fd == -1)
+02295         {
+02296                 nlwarning ("HA: Can't get OS from /proc/self/stat: %s", strerror (errno));
+02297         }
+02298         else
+02299         {
+02300                 char buffer[4096], *p;
+02301                 int len = read(fd, buffer, sizeof(buffer)-1);
+02302                 close(fd);
+02303         
+02304                 buffer[len] = '\0';
+02305                 
+02306                 p = buffer;
+02307                 p = strchr(p, ')')+1;                   /* skip pid */
+02308                 p = skipWS(p);
+02309                 p++;
+02310                 
+02311                 p = skipToken(p);                               /* skip ppid */
+02312                 p = skipToken(p);                               /* skip pgrp */
+02313                 p = skipToken(p);                               /* skip session */
+02314                 p = skipToken(p);                               /* skip tty */
+02315                 p = skipToken(p);                               /* skip tty pgrp */
+02316                 p = skipToken(p);                               /* skip flags */
+02317                 p = skipToken(p);                               /* skip min flt */
+02318                 p = skipToken(p);                               /* skip cmin flt */
+02319                 p = skipToken(p);                               /* skip maj flt */
+02320                 p = skipToken(p);                               /* skip cmaj flt */
+02321                 p = skipToken(p);                               /* utime */
+02322                 p = skipToken(p);                               /* stime */
+02323                 p = skipToken(p);                               /* skip cutime */
+02324                 p = skipToken(p);                               /* skip cstime */
+02325                 p = skipToken(p);                               /* priority */
+02326                 p = skipToken(p);                               /* nice */
+02327                 p = skipToken(p);                               /* skip timeout */
+02328                 p = skipToken(p);                               /* skip it_real_val */
+02329                 p = skipToken(p);                               /* skip start_time */
+02330                 
+02331                 systemMemory = strtoul(p, &p, 10);      /* vsize in bytes */
+02332         }
+02333 
+02334 #endif // NL_OS_WINDOWS
+02335         return systemMemory;
+02336 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getAllocatedSystemMemoryByAllocator  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 2340 of file misc/heap_allocator.cpp. +

+References uint. +

+Referenced by debugStatisticsReport(). +

+

02341 {
+02342         uint nelSystemMemory = 0;
+02343 
+02344         // Build a set of allocated system memory pointers
+02345         std::set<void*> ptrInUse;
+02346 
+02347         // For each main block
+02348         CMainBlock *currentBlock = _MainBlockList;
+02349         while (currentBlock)
+02350         {
+02351                 // Save pointers
+02352                 ptrInUse.insert ((void*)currentBlock);
+02353                 ptrInUse.insert ((void*)(currentBlock->Ptr));
+02354 
+02355                 // Next block
+02356                 currentBlock = currentBlock->Next;
+02357         }
+02358 
+02359 #ifdef NL_OS_WINDOWS
+02360         // Get system memory informations
+02361         HANDLE hHeap[100];
+02362         DWORD heapCount = GetProcessHeaps (100, hHeap);
+02363 
+02364         uint heap;
+02365         for (heap = 0; heap < heapCount; heap++)
+02366         {
+02367                 PROCESS_HEAP_ENTRY entry;
+02368                 entry.lpData = NULL;
+02369                 while (HeapWalk (hHeap[heap], &entry))
+02370                 {
+02371                         if (entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
+02372                         {
+02373                                 // This pointer is already used ?
+02374                                 if ( (ptrInUse.find ((void*)((char*)entry.lpData)) != ptrInUse.end ()) || 
+02375                                         (ptrInUse.find ((void*)((char*)entry.lpData+32)) != ptrInUse.end ()) )
+02376                                         nelSystemMemory += entry.cbData + entry.cbOverhead;
+02377                         }
+02378                 }
+02379         }
+02380 #endif // NL_OS_WINDOWS
+02381         return nelSystemMemory;
+02382 }
+
+

+ + + + +
+ + + + + + + + + +
TBlockAllocationMode NLMISC::CHeapAllocator::getBlockAllocationMode  )  const
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
uint NLMISC::CHeapAllocator::getBlockSize void *  block  )  [static]
+
+ + + + + +
+   + + +

+ +

+Definition at line 631 of file misc/heap_allocator.cpp. +

+References getNodeSize(), and uint. +

+

00632 {
+00633         // Get the node pointer
+00634   //CNodeBegin *node = (CNodeBegin*) ((uint)block - sizeof (CNodeBegin));
+00635 
+00636         return getNodeSize (((CNodeBegin*) ((uint)block - sizeof (CNodeBegin))));
+00637 }
+
+

+ + + + +
+ + + + + + + + + + +
CNodeBegin* NLMISC::CHeapAllocator::getFirstNode CMainBlock mainBlock  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
const CNodeBegin* NLMISC::CHeapAllocator::getFirstNode const CMainBlock mainBlock  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugGetAllocatedMemoryByCategory(), debugGetLBDebugInfoSize(), debugReportMemoryLeak(), debugStatisticsReport(), freeAll(), getAllocatedMemory(), getFragmentationRatio(), getFreeMemory(), initEmptyBlock(), and internalCheckHeap().

+

+ + + + +
+ + + + + + + + + +
float NLMISC::CHeapAllocator::getFragmentationRatio  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1804 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), getFirstNode(), getNextNode(), isNodeUsed(), leaveCriticalSection(), and NLMISC::CHeapAllocator::CMainBlock::Next. +

+

01805 {
+01806         enterCriticalSection ();
+01807 
+01808         // Sum free and used node
+01809         float free = 0;
+01810         float used = 0;
+01811 
+01812         // For each main block
+01813         CMainBlock *currentBlock = _MainBlockList;
+01814         while (currentBlock)
+01815         {
+01816                 // Get the first node
+01817                 const CNodeBegin *current = getFirstNode (currentBlock);
+01818                 while (current)
+01819                 {
+01820                         // Node allocated ?
+01821                         if (isNodeUsed (current))
+01822                                 used++;
+01823                         else
+01824                                 free++;
+01825 
+01826                         // Next node
+01827                         current = getNextNode (current);
+01828                 }
+01829 
+01830                 // Next block
+01831                 currentBlock = currentBlock->Next;
+01832         }
+01833 
+01834         leaveCriticalSection ();
+01835 
+01836         // Return the memory
+01837         if (used != 0)
+01838                 return free / used;
+01839         else
+01840                 return 0;
+01841 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getFreeMemory  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1685 of file misc/heap_allocator.cpp. +

+References checkNode(), enterCriticalSection(), getFirstNode(), getNextNode(), getNodeSize(), getSmallBlock(), isNodeFree(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, and uint. +

+

01686 {
+01687         enterCriticalSection ();
+01688 
+01689         // Sum free memory
+01690         uint memory = 0;
+01691 
+01692         // For each small block
+01693         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01694         while (currentSB)
+01695         {
+01696                 // For each node in this small block pool
+01697                 uint block;
+01698                 for (block=0; block<SmallBlockPoolSize; block++)
+01699                 {
+01700                         // Get the node
+01701                         const CNodeBegin *current = getSmallBlock (currentSB, block);
+01702 
+01703                         // Node allocated ?
+01704                         if (isNodeFree (current))
+01705                                 memory  += getNodeSize (current) + ReleaseHeaderSize;
+01706 
+01707                         // Next node
+01708                         current = getNextNode (current);
+01709                 }
+01710 
+01711                 // Next block
+01712                 currentSB = currentSB->Next;
+01713         }
+01714 
+01715         // For each main block
+01716         CMainBlock *currentBlock = _MainBlockList;
+01717         while (currentBlock)
+01718         {
+01719                 // Get the first node
+01720                 const CNodeBegin *current = getFirstNode (currentBlock);
+01721                 while (current)
+01722                 {
+01723 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+01724                         // Check node
+01725                         checkNode (current, evalMagicNumber (current));
+01726 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+01727 
+01728                         // Node allocated ?
+01729                         if (isNodeFree (current))
+01730                                 memory  += getNodeSize (current) + ReleaseHeaderSize;
+01731 
+01732                         // Next node
+01733                         current = getNextNode (current);
+01734                 }
+01735 
+01736                 // Next block
+01737                 currentBlock = currentBlock->Next;
+01738         }
+01739 
+01740         leaveCriticalSection ();
+01741 
+01742         // Return memory used
+01743         return memory;
+01744 }
+
+

+ + + + +
+ + + + + + + + + + +
CFreeNode* NLMISC::CHeapAllocator::getFreeNode CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
const CFreeNode* NLMISC::CHeapAllocator::getFreeNode const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getMainBlockCount  )  const
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getMainBlockSize  )  const
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + +
const char* NLMISC::CHeapAllocator::getName  )  const
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
CNodeBegin* NLMISC::CHeapAllocator::getNextNode CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
const CNodeBegin* NLMISC::CHeapAllocator::getNextNode const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugGetAllocatedMemoryByCategory(), debugGetLBDebugInfoSize(), debugReportMemoryLeak(), debugStatisticsReport(), free(), getAllocatedMemory(), getFragmentationRatio(), getFreeMemory(), internalCheckHeap(), mergeNode(), and splitNode().

+

+ + + + +
+ + + + + + + + + + +
CNodeBegin* NLMISC::CHeapAllocator::getNextSmallBlock CNodeBegin previous  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
CNodeBegin* NLMISC::CHeapAllocator::getNode CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
const CNodeBegin* NLMISC::CHeapAllocator::getNode const CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
uint NLMISC::CHeapAllocator::getNodeSize const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugGetAllocatedMemoryByCategory(), debugReportMemoryLeak(), debugStatisticsReport(), free(), getAllocatedMemory(), getBlockSize(), getFreeMemory(), initEmptyBlock(), insert(), mergeNode(), and splitNode().

+

+ + + + +
+ + + + + + + + + +
TOutOfMemoryMode NLMISC::CHeapAllocator::getOutOfMemoryMode  )  const
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
CNodeBegin* NLMISC::CHeapAllocator::getSmallBlock CSmallBlockPool smallBlock,
uint  blockIndex
[static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugGetAllocatedMemoryByCategory(), debugReportMemoryLeak(), debugStatisticsReport(), getAllocatedMemory(), getFreeMemory(), and internalCheckHeap().

+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getSmallBlockMemory  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1777 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), leaveCriticalSection(), NLMISC::CHeapAllocator::CSmallBlockPool::Next, NL_HEAP_NODE_END_SIZE, NLMISC::CHeapAllocator::CSmallBlockPool::Size, and uint. +

+

01778 {
+01779         enterCriticalSection ();
+01780 
+01781         // Sum total memory
+01782         uint memory = 0;
+01783 
+01784         // For each small block
+01785         CSmallBlockPool *currentSB = (CSmallBlockPool *)_SmallBlockPool;
+01786         while (currentSB)
+01787         {
+01788                 // Get block size
+01789                 memory += sizeof(CSmallBlockPool) + SmallBlockPoolSize * (sizeof(CNodeBegin) + currentSB->Size + 
+01790                                         NL_HEAP_NODE_END_SIZE);
+01791 
+01792                 // Next block
+01793                 currentSB = currentSB->Next;
+01794         }
+01795 
+01796         leaveCriticalSection ();
+01797 
+01798         // Return the memory
+01799         return memory;
+01800 }
+
+

+ + + + +
+ + + + + + + + + +
uint NLMISC::CHeapAllocator::getTotalMemoryUsed  )  const
+
+ + + + + +
+   + + +

+ +

+Definition at line 1748 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CMainBlock::Size, and uint. +

+

01749 {
+01750         enterCriticalSection ();
+01751 
+01752         // Sum total memory
+01753         uint memory = 0;
+01754 
+01755         // For each main block
+01756         CMainBlock *currentBlock = _MainBlockList;
+01757         while (currentBlock)
+01758         {
+01759                 // Get block size
+01760                 memory += currentBlock->Size;
+01761 
+01762                 // Sum the arrays
+01763                 memory += sizeof (CMainBlock);
+01764 
+01765                 // Next block
+01766                 currentBlock = currentBlock->Next;
+01767         }
+01768 
+01769         leaveCriticalSection ();
+01770 
+01771         // Return the memory
+01772         return memory;
+01773 }
+
+

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

+ +

+Definition at line 576 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNodeBegin::BeginMarkers, NLMISC::CHeapAllocator::CNodeBegin::EndMagicNumber, NLMISC::CHeapAllocator::CNodeEnd::EndMarkers, getFirstNode(), getNodeSize(), internalAssert, NL_HEAP_NODE_END_SIZE, NL_UPDATE_MAGIC_NUMBER, NLMISC::CHeapAllocator::CNodeBegin::Previous, NLMISC::CHeapAllocator::CMainBlock::Ptr, setNodeFree(), setNodeLast(), setNodeSize(), NLMISC::CHeapAllocator::CMainBlock::Size, uint, uint32, and uint8. +

+Referenced by freeAll(). +

+

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

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

+ +

+Definition at line 137 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNullNode::FreeNode, getNodeSize(), isNodeRed(), NLMISC::CHeapAllocator::CFreeNode::Left, NL_UPDATE_MAGIC_NUMBER_FREE_NODE, NLMISC::CHeapAllocator::CFreeNode::Right, rotateLeft(), rotateRight(), setNodeBlack(), setNodeRed(), x, and y. +

+Referenced by free(), and freeAll(). +

+

00138 {
+00139     CHeapAllocator::CFreeNode *current, *parent;
+00140 
+00141     // Find future parent
+00142         current = _FreeTreeRoot;
+00143         parent = NULL;
+00144         while (current != &_NullNode.FreeNode)
+00145         {
+00146                 parent = current;
+00147                 current = (getNodeSize (getNode (x)) <= getNodeSize (getNode (current)) ) ? current->Left : current->Right;
+00148         }
+00149 
+00150         // Setup new node
+00151         x->Parent = parent;
+00152         x->Left = &_NullNode.FreeNode;
+00153         x->Right = &_NullNode.FreeNode;
+00154         setNodeRed (x);
+00155 
+00156         // Insert node in tree
+00157         if (parent)
+00158         {
+00159                 if(getNodeSize (getNode (x)) <= getNodeSize (getNode (parent)))
+00160                         parent->Left = x;
+00161                 else
+00162                         parent->Right = x;
+00163                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (parent);
+00164         }
+00165         else
+00166         {
+00167                 _FreeTreeRoot = x;
+00168         }
+00169 
+00170         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x);
+00171 
+00172     // Maintain Red-Black tree balance
+00173     // After inserting node x
+00174         // Check Red-Black properties
+00175 
+00176         while (x != _FreeTreeRoot && isNodeRed (x->Parent))
+00177         {
+00178                 // We have a violation
+00179                 if (x->Parent == x->Parent->Parent->Left)
+00180                 {
+00181                         CHeapAllocator::CFreeNode *y = x->Parent->Parent->Right;
+00182                         if (isNodeRed (y))
+00183                         {
+00184                                 // Uncle is RED
+00185                 setNodeBlack (x->Parent);
+00186                                 setNodeBlack (y);
+00187                                 setNodeRed (x->Parent->Parent);
+00188 
+00189                                 // Crc node
+00190                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y);
+00191                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent);
+00192                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent->Parent);
+00193 
+00194                                 x = x->Parent->Parent;
+00195                         }
+00196                         else
+00197                         {
+00198                 // Uncle is Black
+00199                                 if (x == x->Parent->Right)
+00200                                 {
+00201                     // Make x a left child
+00202                                         x = x->Parent;
+00203                     rotateLeft(x);
+00204                                 }
+00205 
+00206                                 // Recolor and rotate
+00207                                 setNodeBlack (x->Parent);
+00208                                 setNodeRed (x->Parent->Parent);
+00209 
+00210                                 rotateRight (x->Parent->Parent);
+00211 
+00212                                 // Crc node
+00213                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent);
+00214                         }
+00215                 }
+00216                 else
+00217                 {
+00218                         // Mirror image of above code
+00219                         CHeapAllocator::CFreeNode *y = x->Parent->Parent->Left;
+00220                         if (isNodeRed (y))
+00221                         {                
+00222                                 // Uncle is Red
+00223                                 setNodeBlack (x->Parent);
+00224                                 setNodeBlack (y);
+00225                                 setNodeRed (x->Parent->Parent);
+00226 
+00227                                 // Crc node
+00228                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (y);
+00229                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent);
+00230                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent->Parent);
+00231 
+00232                                 x = x->Parent->Parent;
+00233                         }
+00234                         else
+00235                         {
+00236                 // Uncle is Black
+00237                 if (x == x->Parent->Left) 
+00238                                 {
+00239                     x = x->Parent;                    
+00240                                         rotateRight(x);
+00241                 }
+00242                                 setNodeBlack (x->Parent);
+00243                 setNodeRed (x->Parent->Parent);
+00244 
+00245                 rotateLeft (x->Parent->Parent);
+00246 
+00247                                 // Crc node
+00248                                 NL_UPDATE_MAGIC_NUMBER_FREE_NODE (x->Parent);
+00249                         }        
+00250                 }    
+00251         }
+00252     setNodeBlack (_FreeTreeRoot);
+00253 
+00254         // Crc node
+00255         NL_UPDATE_MAGIC_NUMBER_FREE_NODE (_FreeTreeRoot);
+00256 }
+
+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::internalCheckHeap bool  stopOnError  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Definition at line 2074 of file misc/heap_allocator.cpp. +

+References checkFreeNode(), checkNodeLB(), checkNodeSB(), enterCriticalSection(), getFirstNode(), getNextNode(), getSmallBlock(), internalAssert, leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, NLMISC::CHeapAllocator::CSmallBlockPool::Next, and uint. +

+Referenced by checkHeap(), and free(). +

+

02075 {
+02076         enterCriticalSection ();
+02077 
+02078         // For each small blocks
+02079         CSmallBlockPool *pool = (CSmallBlockPool*)_SmallBlockPool;
+02080         while (pool)
+02081         {
+02082                 // For each small block
+02083                 uint smallBlock;
+02084                 CNodeBegin      *previous = NULL;
+02085                 for (smallBlock=0; smallBlock<SmallBlockPoolSize; smallBlock++)
+02086                 {
+02087                         // Get the small block
+02088                         CNodeBegin      *node = getSmallBlock (pool, smallBlock);
+02089                         CNodeBegin      *next = (smallBlock+1<SmallBlockPoolSize) ? getSmallBlock (pool, smallBlock+1) : NULL;
+02090 
+02091                         // Check node
+02092                         checkNodeSB (pool, previous, node, next, stopOnError);
+02093 
+02094                         previous = node;
+02095                 }
+02096 
+02097                 // Next pool
+02098                 pool = pool->Next;
+02099         }
+02100         
+02101         // For each main block
+02102         CMainBlock *currentBlock = _MainBlockList;
+02103         while (currentBlock)
+02104         {
+02105                 // Get the nodes
+02106                 const CNodeBegin *previous = NULL;
+02107                 const CNodeBegin *current = getFirstNode (currentBlock);
+02108                 internalAssert (current);       // Should have at least one block in the main block
+02109                 const CNodeBegin *next;
+02110                 
+02111                 // For each node
+02112                 while (current)
+02113                 {
+02114                         // Get next
+02115                         next = getNextNode (current);
+02116 
+02117                         // Return Error ?
+02118                         if (!checkNodeLB (currentBlock, previous, current, next, stopOnError))
+02119                                 return false;
+02120 
+02121                         // Next
+02122                         previous = current;
+02123                         current = next;
+02124                 }
+02125 
+02126                 // Next block
+02127                 currentBlock = currentBlock->Next;
+02128         }
+02129 
+02130         // Check free tree
+02131         if (!checkFreeNode (_FreeTreeRoot, stopOnError, true))
+02132                 return false;
+02133 
+02134         leaveCriticalSection ();
+02135 
+02136         // Ok, no problem
+02137         return true;
+02138 }
+
+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeBlack const CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by erase().

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeFree const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugStatisticsReport(), free(), and getFreeMemory().

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeLast const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeRed const CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by erase(), and insert().

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeSmall const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::isNodeUsed const CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by debugGetAllocatedMemoryByCategory(), debugReportMemoryLeak(), debugStatisticsReport(), getAllocatedMemory(), and getFragmentationRatio().

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::leaveCriticalSection  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by CHeapAllocator(), debugGetAllocatedMemoryByCategory(), debugGetLBDebugInfoSize(), debugGetSBDebugInfoSize(), freeAll(), getAllocatedMemory(), getFragmentationRatio(), getFreeMemory(), getSmallBlockMemory(), getTotalMemoryUsed(), internalCheckHeap(), releaseMemory(), and setName().

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::leaveCriticalSectionLB  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by free().

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::leaveCriticalSectionSB  )  const [private]
+
+ + + + + +
+   + + +

+ +

+Referenced by free().

+

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

+ +

+Definition at line 527 of file misc/heap_allocator.cpp. +

+References getNextNode(), getNodeSize(), internalAssert, NL_HEAP_NODE_END_SIZE, NL_UPDATE_MAGIC_NUMBER, NLMISC::CHeapAllocator::CNodeBegin::Previous, setNodeLast(), setNodeSize(), uint32, and uint8. +

+Referenced by free(). +

+

00528 {
+00529         // Get the previous node to merge with
+00530         CNodeBegin *previous = node->Previous;
+00531         internalAssert (getNextNode (previous) == node);
+00532         internalAssert (previous);
+00533         internalAssert (isNodeFree (previous));
+00534 
+00535         // New size
+00536         setNodeSize (previous, getNodeSize (previous) + getNodeSize (node) + sizeof (CNodeBegin) + NL_HEAP_NODE_END_SIZE);
+00537 
+00538 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00539         // Set end pointers
+00540         previous->EndMagicNumber = (uint32*)((uint8*)previous + getNodeSize (previous) + sizeof (CNodeBegin));
+00541 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00542 
+00543         // Get the next node to relink
+00544         CNodeBegin *next = getNextNode (node);
+00545         if (next)
+00546         {
+00547                 // Relink
+00548                 next->Previous = previous;
+00549 
+00550                 NL_UPDATE_MAGIC_NUMBER (next);
+00551         }
+00552 
+00553         // Get the last flag
+00554         setNodeLast (previous, isNodeLast (node));
+00555 
+00556 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00557 
+00558         // todo align
+00559 
+00560         // Clear the node informations
+00561         memset (((uint8*)node + getNodeSize (node) + sizeof (CNodeBegin)), DeletedMemory, NL_HEAP_NODE_END_SIZE);
+00562         memset (node, DeletedMemory, sizeof (CNodeBegin));
+00563 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00564 }
+
+

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

+

+

+ + + + +
+ + + + + + + + + +
void NLMISC::CHeapAllocator::releaseMemory  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 1879 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), freeBlock(), NLMISC::CHeapAllocator::CNullNode::FreeNode, leaveCriticalSection(), NLMISC::CHeapAllocator::CMainBlock::Next, and NLMISC::CHeapAllocator::CMainBlock::Ptr. +

+Referenced by ~CHeapAllocator(). +

+

01880 {
+01881         enterCriticalSection ();
+01882 
+01883         // Clear the free tree
+01884         _FreeTreeRoot = &_NullNode.FreeNode;
+01885 
+01886         // For each main block
+01887         CMainBlock *currentBlock = _MainBlockList;
+01888         while (currentBlock)
+01889         {
+01890                 freeBlock (currentBlock->Ptr);
+01891 
+01892                 // Next block
+01893                 CMainBlock *toDelete = currentBlock;
+01894                 currentBlock = toDelete->Next;
+01895                 ::free (toDelete);
+01896         }
+01897 
+01898         // Erase block node
+01899         _MainBlockList = NULL;
+01900 
+01901         leaveCriticalSection ();
+01902 }
+
+

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

+ +

+Referenced by erase(), and insert().

+

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

+ +

+Referenced by erase(), and insert().

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setBlockAllocationMode TBlockAllocationMode  mode  ) 
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::setMainBlockCount uint  blockCount  ) 
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
bool NLMISC::CHeapAllocator::setMainBlockSize uint  mainBlockSize  ) 
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setName const char *  name  ) 
+
+ + + + + +
+   + + +

+ +

+Definition at line 2160 of file misc/heap_allocator.cpp. +

+References enterCriticalSection(), and leaveCriticalSection(). +

+

02161 {
+02162         enterCriticalSection ();
+02163 
+02164         strncpy (_Name, name, NameLength-1);
+02165 
+02166         leaveCriticalSection ();
+02167 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NLMISC::CHeapAllocator::setNextSmallBlock CNodeBegin previous,
CNodeBegin next
[static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeBlack CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by CHeapAllocator(), erase(), and insert().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeColor CFreeNode current,
bool  red
[static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by erase().

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeFree CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by free(), initEmptyBlock(), and splitNode().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeLast CNodeBegin current,
bool  last
[static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by initEmptyBlock(), mergeNode(), and splitNode().

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeRed CFreeNode current  )  [static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by erase(), and insert().

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeSize CNodeBegin current,
uint  size
[static, private]
+
+ + + + + +
+   + + +

+ +

+Referenced by initEmptyBlock(), mergeNode(), and splitNode().

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setNodeUsed CNodeBegin current  )  [static, private]
+
+ + + + + +
+   + + +

+

+

+ + + + +
+ + + + + + + + + + +
void NLMISC::CHeapAllocator::setOutOfMemoryMode TOutOfMemoryMode  mode  ) 
+
+ + + + + +
+   + + +

+

+

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

+ +

+Definition at line 442 of file misc/heap_allocator.cpp. +

+References NLMISC::CHeapAllocator::CNodeBegin::BeginMarkers, NLMISC::CHeapAllocator::CNodeBegin::Category, NLMISC::CHeapAllocator::CNodeBegin::EndMagicNumber, NLMISC::CHeapAllocator::CNodeEnd::EndMarkers, NLMISC::CHeapAllocator::CNodeBegin::File, getNextNode(), getNodeSize(), NLMISC::CHeapAllocator::CNodeBegin::Heap, internalAssert, NLMISC::CHeapAllocator::CNodeBegin::Line, NL_HEAP_NODE_END_SIZE, NL_UPDATE_MAGIC_NUMBER, NLMISC::CHeapAllocator::CNodeBegin::Previous, setNodeFree(), setNodeLast(), setNodeSize(), uint, uint32, and uint8. +

+

00443 {
+00444         // Should be smaller than node size
+00445         internalAssert (newSize <= getNodeSize (node));
+00446 
+00447         // Align size
+00448         uint allignedSize = (newSize&~(Align-1)) + (( (newSize&(Align-1))==0 ) ? 0 : Align);
+00449         if (allignedSize <= UserDataBlockSizeMin)
+00450                 allignedSize = UserDataBlockSizeMin;
+00451 
+00452 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00453         // End magic number aligned on new size
+00454         node->EndMagicNumber = (uint32*)((uint8*)node + newSize + sizeof (CNodeBegin));
+00455 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00456 
+00457         // Rest is empty ?
+00458         if ( getNodeSize (node) - allignedSize < UserDataBlockSizeMin + sizeof (CNodeBegin) + NL_HEAP_NODE_END_SIZE )
+00459                 // No split
+00460                 return NULL;
+00461 
+00462         // New node begin structure
+00463         CNodeBegin *newNode = (CNodeBegin*)((uint8*)node + sizeof (CNodeBegin) + allignedSize + NL_HEAP_NODE_END_SIZE );
+00464 
+00465         // Fill the new node header
+00466 
+00467         // Size
+00468         setNodeSize (newNode, getNodeSize (node) - allignedSize - sizeof (CNodeBegin) - NL_HEAP_NODE_END_SIZE);
+00469 
+00470         // Set the node free
+00471         setNodeFree (newNode);
+00472 
+00473         // Set the previous node pointer
+00474         newNode->Previous = node;
+00475 
+00476         // Last flag
+00477         setNodeLast (newNode, isNodeLast (node));
+00478 
+00479 #ifndef NLMISC_HEAP_ALLOCATION_NDEBUG
+00480         // Begin markers
+00481         memset (newNode->BeginMarkers, BeginNodeMarkers, CNodeBegin::MarkerSize-1);
+00482         newNode->BeginMarkers[CNodeBegin::MarkerSize-1] = 0;
+00483 
+00484         // End pointer
+00485         newNode->EndMagicNumber = (uint32*)((uint8*)newNode + getNodeSize (newNode) + sizeof (CNodeBegin));
+00486 
+00487         // End markers
+00488         CNodeEnd *endNode = (CNodeEnd*)((uint8*)newNode + getNodeSize (newNode) + sizeof (CNodeBegin));
+00489         memset (endNode->EndMarkers, EndNodeMarkers, CNodeEnd::MarkerSize-1);
+00490         endNode->EndMarkers[CNodeEnd::MarkerSize-1] = 0;
+00491 
+00492         // No source informations
+00493         newNode->File = NULL;
+00494         newNode->Line = 0xffff;
+00495         node->AllocateNumber = 0xffffffff;
+00496         memset (newNode->Category, 0, CategoryStringLength);
+00497 
+00498         // Heap pointer
+00499         newNode->Heap = this;
+00500 #endif // NLMISC_HEAP_ALLOCATION_NDEBUG
+00501 
+00502         // Get next node
+00503         CNodeBegin *next = getNextNode (node);
+00504         if (next)
+00505         {
+00506                 // Set previous
+00507                 next->Previous = newNode;
+00508 
+00509                 NL_UPDATE_MAGIC_NUMBER (next);
+00510         }
+00511 
+00512         // Should be big enough
+00513         internalAssert (getNodeSize (newNode) >= UserDataBlockSizeMin);
+00514 
+00515         // New size of the first node
+00516         setNodeSize (node, allignedSize);
+00517 
+00518         // No more the last
+00519         setNodeLast (node, false);
+00520 
+00521         // Return new node
+00522         return newNode;
+00523 }
+
+


Field Documentation

+

+ + + + +
+ + +
uint32 NLMISC::CHeapAllocator::_AllocateCount [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 393 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
bool NLMISC::CHeapAllocator::_AlwaysCheck [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 380 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
TBlockAllocationMode NLMISC::CHeapAllocator::_BlockAllocationMode [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 377 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
uint NLMISC::CHeapAllocator::_BlockCount [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 376 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CTDS NLMISC::CHeapAllocator::_CategoryStack [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 479 of file include/nel/misc/heap_allocator.h.

+

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

+ +

+Definition at line 452 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CFreeNode* NLMISC::CHeapAllocator::_FreeTreeRoot [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 387 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CMainBlock* NLMISC::CHeapAllocator::_MainBlockList [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 384 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
uint NLMISC::CHeapAllocator::_MainBlockSize [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 375 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CAllocatorMutex NLMISC::CHeapAllocator::_MutexLB [mutable, private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 389 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CAllocatorMutex NLMISC::CHeapAllocator::_MutexSB [mutable, private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 455 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
char NLMISC::CHeapAllocator::_Name[NameLength] [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 391 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
CNullNode NLMISC::CHeapAllocator::_NullNode [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 388 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
TOutOfMemoryMode NLMISC::CHeapAllocator::_OutOfMemoryMode [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 378 of file include/nel/misc/heap_allocator.h.

+

+ + + + +
+ + +
volatile CSmallBlockPool* NLMISC::CHeapAllocator::_SmallBlockPool [private] +
+
+ + + + + +
+   + + +

+ +

+Definition at line 453 of file include/nel/misc/heap_allocator.h.

+


The documentation for this class was generated from the following files: +
Generated on Tue Mar 16 13:16:09 2004 for NeL by + +doxygen +1.3.6
+ + -- cgit v1.2.1