#include <heap_allocator.h>
|
|
Definition at line 106 of file include/nel/misc/heap_allocator.h. |
|
|
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 };
|
|
|
Definition at line 205 of file include/nel/misc/heap_allocator.h.
00206 {
00207 FreeNodeBlockSize = 128,
00208 FreeNodeBlockSizeShift = 7,
00209 FreeNodeBlockSizeMask = 0x7f
00210 };
|
|
|
Definition at line 213 of file include/nel/misc/heap_allocator.h.
00214 {
00215 Align = 8,
00216 BlockDataSizeMin = 1<<4
00217 };
|
|
|
Definition at line 330 of file include/nel/misc/heap_allocator.h.
00331 {
00332 UserDataBlockSizeMin = sizeof(CFreeNode)
00333 };
|
|
|
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 };
|
|
|
Block allocation mode.
Definition at line 85 of file include/nel/misc/heap_allocator.h.
|
|
|
Out of memory signal
Definition at line 97 of file include/nel/misc/heap_allocator.h.
00098 {
00100 ThrowException,
00101
00103 ReturnNull
00104 };
|
|
||||||||||||||||||||
|
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 }
|
|
|
Definition at line 129 of file misc/heap_allocator.cpp. References releaseMemory().
00130 {
00131 // Release all memory used
00132 releaseMemory ();
00133 }
|
|
||||||||||||||||||||
|
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 }
|
|
|
Definition at line 2059 of file misc/heap_allocator.cpp. References size, uint, and uint8.
|
|
||||||||||||||||
|
Referenced by internalCheckHeap(). |
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
Referenced by internalCheckHeap(). |
|
||||||||||||||||||||||||
|
Referenced by internalCheckHeap(). |
|
||||||||||||||||
|
|
|
|
Definition at line 2143 of file misc/heap_allocator.cpp.
02144 {
02145 _AlwaysCheck = alwaysCheck;
02146 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 2152 of file misc/heap_allocator.cpp.
02153 {
02154 return _AlwaysCheck;
02155 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
|
Referenced by free(). |
|
|
Referenced by free(). |
|
|
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 }
|
|
|
|
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 2067 of file misc/heap_allocator.cpp. References uint8. Referenced by releaseMemory().
02068 {
02069 ::free (block);
02070 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
|
|
|
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 }
|
|
|
|
|
|
|
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 }
|
|
|
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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
Referenced by debugGetAllocatedMemoryByCategory(), debugReportMemoryLeak(), debugStatisticsReport(), getAllocatedMemory(), getFreeMemory(), and internalCheckHeap(). |
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Referenced by erase(). |
|
|
Referenced by debugStatisticsReport(), free(), and getFreeMemory(). |
|
|
|
|
|
|
|
|
|
|
|
Referenced by debugGetAllocatedMemoryByCategory(), debugReportMemoryLeak(), debugStatisticsReport(), getAllocatedMemory(), and getFragmentationRatio(). |
|
|
|
Referenced by free(). |
|
|
Referenced by free(). |
|
|
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 }
|
|
||||||||||||||||||||||||
|
|
|
|
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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 }
|
|
||||||||||||
|
|
|
|
Referenced by CHeapAllocator(), erase(), and insert(). |
|
||||||||||||
|
Referenced by erase(). |
|
|
Referenced by free(), initEmptyBlock(), and splitNode(). |
|
||||||||||||
|
Referenced by initEmptyBlock(), mergeNode(), and splitNode(). |
|
|
|
|
||||||||||||
|
Referenced by initEmptyBlock(), mergeNode(), and splitNode(). |
|
|
|
|
|
|
|
||||||||||||
|
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 }
|
|
|
Definition at line 393 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 380 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 377 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 376 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 479 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 452 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 387 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 384 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 375 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 389 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 455 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 391 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 388 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 378 of file include/nel/misc/heap_allocator.h. |
|
|
Definition at line 453 of file include/nel/misc/heap_allocator.h. |
1.3.6