#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. |