"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSMemLib/Src/Allocators/LSAStdAllocatorHeap.h

00001 
00032 #ifndef __LSA_STDALLOCATORHEAP_H__
00033 #define __LSA_STDALLOCATORHEAP_H__
00034 
00035 #include "../OSHeap/LSAOsHeap.h"
00036 #if defined( LSA_USE_FLOAT_OPTIMIZATIONS )
00037 #include <cmath>
00038 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00039 
00040 
00041 namespace lsa {
00042 
00048         class CStdAllocatorHeap {
00049                 // Only the CStdAllocator class can create this object.
00050                 friend class                                                                    CStdAllocator;
00051 
00052         public :
00053                 // == Functions.
00061                 LSVOID * LSE_CALL                                                               Alloc( LSA_SIZE _sSize, LSUINT32 _ui32Align = LSA_MIN_ALIGN                                             LSA_DEBUGPARMSDECL );
00062 
00069                 LSBOOL LSE_CALL                                                                 Free( LSVOID * _pvAddr );
00070 
00077                 LSBOOL LSE_CALL                                                                 IsEmpty( LSBOOL _bReport ) const;
00078 
00082                 LSVOID LSE_CALL                                                                 Trash();
00083 
00093                 LSA_SIZE LSE_CALL                                                               PrintAllocations( LSUINT32 _ui32Count = 0UL, LSUINT32 _ui32End = 0xFFFFFFFFUL ) const;
00094 
00100                 LSE_INLINE LSA_SIZE LSE_CALL                                    GetHeapSize() const;
00101 
00109                 static LSUINT32 LSE_CALL                                                GetAllocationCounter();
00110 
00111 
00112         protected :
00113                 // == Various constructors.
00114                 LSE_INLINE LSE_CALL                                                             CStdAllocatorHeap();
00115 
00116         protected :
00117                 // == Types.
00121 #pragma pack( push, 1 )
00122                 typedef struct LSA_FREEHEADER {
00126                         LSA_FREEHEADER *                                                        pfhNextFree;
00127 
00131                         LSA_FREEHEADER *                                                        pfhPrevFree;
00132 
00136                         LSA_FREEHEADER *                                                        pfhNextInHash;
00137 
00141                         LSA_SIZE                                                                        sActualSize;
00142                 } * LPLSA_FREEHEADER, * const LPCLSA_FREEHEADER;
00143 #pragma pack( pop )
00144 
00149 #pragma pack( push, 1 )
00150                 typedef struct LSA_ALLOCATIONHEADER {
00154                         LPLSA_FREEHEADER                                                        pfhPrevFree;
00155                         
00159                         LSA_ALLOCATIONHEADER *                                          pahNext;
00160                         
00164                         LSA_ALLOCATIONHEADER *                                          pahNextInHash;
00165                         
00171                         LSUINT32                                                                        ui32Size                : 31;
00172                         
00176                         LSUINT32                                                                        ui32Alignment   : 1;
00177 
00178                         // Debug information, if any.
00179 #ifdef LSA_DEBUG
00180 
00183                         LSUINT32                                                                        ui32Line;
00184                         
00188                         const LSCHAR *                                                          pcFile;
00189                         
00193                         LSUINT32                                                                        ui32Number;
00194 #endif  // #ifdef LSA_DEBUG
00195                 } * LPLSA_ALLOCATIONHEADER, * const LPCLSA_ALLOCATIONHEADER;
00196 #pragma pack( pop )
00197 
00198 
00199         protected :
00200                 // == Functions.
00207                 LSE_INLINE LSVOID LSE_CALL                                              Set( LSVOID * _pvHeap, LSA_SIZE _sSizeOfHeap );
00208 
00218                 LSVOID * LSE_CALL                                                               ReAlloc( LPLSA_ALLOCATIONHEADER &_lpahHeader, LSVOID * _pvAddr, LSA_SIZE _sSize LSA_DEBUGPARMSDECL );
00219 
00220                 // Given the address of a block, get the address returned to the user.
00221                 LSE_INLINE static LSVOID * LSE_CALL                             GetStartAddress( const LPLSA_ALLOCATIONHEADER _lpahHeader );
00222 
00223                 // Get the actual size of a block given the requested size, alignment, and start address.
00224                 LSE_INLINE static LSA_SIZE LSE_CALL                             GetActualSizeOfBlock( LSVOID * _pvAddr, LSA_SIZE _sSize, LSUINT32 _ui32Align );
00225 
00226                 // Get the size of an allocated block.
00227                 LSE_INLINE static LSA_SIZE LSE_CALL                             GetSize( const LPLSA_ALLOCATIONHEADER _lpahHeader );
00228 
00229                 // Given an address returned to the user, generate a hash key.
00230                 LSE_INLINE LSUINT32 LSE_CALL                                    GetHashKey( LSVOID * _pvAddr ) const;
00231 
00232                 // Given a size, generate a hash key.
00233                 LSE_INLINE static LSUINT32 LSE_CALL                             GetHashKey( LSA_SIZE _sSize );
00234 
00235                 // Round up to the nearest alignment.
00236                 LSE_INLINE static LSA_SIZE LSE_CALL                             RoundUp( LSA_SIZE _sSize );
00237 
00238                 // Create a size key for allocation blocks.
00239                 LSE_INLINE static LSUINT32 LSE_CALL                             CreateSizeKey( LSA_SIZE _sSize );
00240 
00241                 // Get the alignment in decimal form given an alignment key.
00242                 LSE_INLINE static LSUINT32 LSE_CALL                             GetAlignment( LSUINT32 _ui32Key );
00243 
00244                 // Get the allocation block previous to the given block, or NULL if there is none.
00245                 LPLSA_ALLOCATIONHEADER LSE_CALL                                 GetPrevAlloc( LPLSA_ALLOCATIONHEADER _pahFrom ) const;
00246 
00247                 // Add an allocation.  Does not remove free blocks or cut anything.  Assumes the address at _pvAddr
00248                 //      is ready to go.
00249                 LSVOID * LSE_CALL                                                               AddAllocInternal( LPLSA_FREEHEADER _lpfhPrevFree,
00250                         LPLSA_ALLOCATIONHEADER _lpahNextAllocated,
00251                         LSVOID * _pvAddr, LSA_SIZE _sSize, LSUINT32 _ui32Align
00252                         LSA_DEBUGPARMSDECL );
00253 
00254                 // Add an allocation at the given address.  The given address is assumed to be the header of a free
00255                 //      block which must be adjusted or removed to make room for the allocation block.  Performs all
00256                 //      necessary operations for adding the allocation block.
00257                 LSVOID * LSE_CALL                                                               AddAlloc( LPLSA_ALLOCATIONHEADER _lpahNextAllocated,
00258                         LSVOID * _pvAddr, LSA_SIZE _sSize, LSUINT32 _ui32Align
00259                         LSA_DEBUGPARMSDECL );
00260 
00261                 // Remove an allocation.  Does all merging and fixing, leaving in a stable state.
00262                 LSVOID LSE_CALL                                                                 RemAlloc( LPLSA_ALLOCATIONHEADER _lpahAllocated );
00263 
00264                 // Add a free-store block without merging or fixing-up.
00265                 LSVOID LSE_CALL                                                                 AddFreeBlockInternal( LPLSA_FREEHEADER _lpfhAfterMe, LPLSA_FREEHEADER _lpfhBeforeMe,
00266                         LSVOID * _pvAddr, LSA_SIZE _sSize );
00267 
00268                 // Remove a free-store block.  Does not chop, merge, or fix-up.
00269                 LSVOID LSE_CALL                                                                 RemFreeBlockInternal( LPLSA_FREEHEADER _lpfhRemoveMe );
00270 
00271                 // Add a free-store block.  Performs merging and fixing.
00272                 LSVOID LSE_CALL                                                                 AddFreeBlock( LPLSA_FREEHEADER _lpfhAfterMe, LPLSA_FREEHEADER _lpfhBeforeMe,
00273                         LSVOID * _pvAddr, LSA_SIZE _sSize );
00274 
00275                 // Merge connected free-store blocks.
00276                 LSBOOL LSE_CALL                                                                 MergeFreeStoreBlocks( LPLSA_FREEHEADER _lpfhFirst );
00277 
00278                 // Get the head of the allocation list.
00279                 LSE_INLINE LPLSA_ALLOCATIONHEADER LSE_CALL              GetAllocationHead() const;
00280 
00281                 // Get the next allocated block after a free block or NULL if there are none.
00282                 LSE_INLINE LPLSA_ALLOCATIONHEADER LSE_CALL              GetNextAllocatedBlock( LPLSA_FREEHEADER _lpAfterMe ) const;
00283 
00284                 // Get the next free block after the given allocated block, or NULL for none.
00285                 LSE_INLINE LPLSA_FREEHEADER LSE_CALL                    GetNextFreeBlock( LPLSA_ALLOCATIONHEADER _lpahAfterMe );
00286 
00287                 // Fix up the free pointers on allocated blocks following a free block.
00288                 LSE_INLINE LSVOID LSE_CALL                                              FixUpAllocationFreeBlockPointers( LPLSA_FREEHEADER _lpfhAfterMe );
00289 
00290                 // In a linked-list of allocated blocks, replace each elementís previous free pointer with the one given
00291                 //      if it matches the provided original free-block pointer.  Stops scanning at the first block that does
00292                 //      not match the given key.
00293                 LSE_INLINE LSVOID LSE_CALL                                              ReplaceAllocationFreeBlockPointers( LPLSA_ALLOCATIONHEADER _lpahStart, LPLSA_FREEHEADER _lpfhReplaceMe, LPLSA_FREEHEADER _lpfhWithMe );
00294 
00295                 // Find a free-store block large enough for a given allocation size and alignment.
00296                 LPLSA_FREEHEADER LSE_CALL                                               FindFreeStoreBlock( LSA_SIZE _sSize, LSUINT32 _ui32Align );
00297 
00298                 // Find an allocated block given its address.
00299                 LSE_INLINE LPLSA_ALLOCATIONHEADER LSE_CALL              FindAllocationBlock( LSVOID * _pvAddr );
00300 
00301                 // Additional debug functions.
00302 #ifdef LSA_DEBUG
00303                 // Print free blocks.
00304                 LSVOID LSE_CALL                                                                 PrintFreeBlocks() const;
00305 
00306                 // Verify free blocks.
00307                 LSVOID LSE_CALL                                                                 VerifyFreeBlocks() const;
00308 
00309                 // Verify allocated blocks.
00310                 LSVOID LSE_CALL                                                                 VerifyAllocatedBlocks() const;
00311 
00317                 static LSVOID LSE_CALL                                                  PrintAllocation( const LPLSA_ALLOCATIONHEADER _lpahHeader );
00318 #endif  // #ifdef LSA_DEBUG
00319 
00320                 // == Members.
00324                 LSVOID *                                                                                m_pvHeap;
00325                 
00329                 LSA_SIZE                                                                                m_sSize;
00330 
00334                 CStdAllocatorHeap *                                                             m_psahNext;
00335 
00339                 LPLSA_ALLOCATIONHEADER                                                  m_lpahAllocatedBlocks[LSA_BUCKETS];
00340 
00344                 LPLSA_FREEHEADER                                                                m_lpfhFreeBlocks[LSA_BUCKETS];
00345 
00349                 LPLSA_FREEHEADER                                                                m_lpfhFreeHead;
00350 
00354                 LSUINT16                                                                                m_usLowestFreeBlockInHashTable;
00355 
00356 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00357 
00360                 LSDOUBLE                                                                                m_dInvSize;
00361 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00362 
00363 #ifdef LSA_DEBUG
00364 
00367                 static LSUINT32                                                                 m_ui32AllocCount;
00368 #endif  // #ifdef LSA_DEBUG
00369 
00370 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00371 
00374                 static LSBOOL                                                                   m_bMadeTable;
00375 
00379                 static LSDOUBLE                                                                 m_dSinTable[0x10000];
00380 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00381         };
00382 
00383 
00384         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00385         // DEFINITIONS
00386         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00387         // == Various constructors.
00388         LSE_INLINE LSE_CALL CStdAllocatorHeap::CStdAllocatorHeap() :
00389 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00390                 m_dInvSize( 0.0 ),
00391 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00392                 m_sSize( 0 ),
00393                 m_pvHeap( NULL ),
00394                 //m_lpahAllocatedHead( NULL ),
00395                 m_lpfhFreeHead( NULL ),
00396                 m_psahNext( NULL ),
00397                 m_usLowestFreeBlockInHashTable( LSA_BUCKETS - 1 ) {
00398                 for ( LSUINT32 I = 0; I < LSA_BUCKETS; ++I ) {
00399                         m_lpahAllocatedBlocks[I] = NULL;
00400                         m_lpfhFreeBlocks[I] = NULL;
00401                 }
00402 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00403                 if ( !m_bMadeTable ) {
00404                         for ( LSINT32 I = 0x10000; --I >= 0; ) {
00405                                 m_dSinTable[I] = ::sin( (2.0 * 3.1415926535897932384626433832795 / 0x10000) * I );
00406                         }
00407                         m_bMadeTable = true;
00408                 }
00409 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00410         }
00411 
00412         // == Functions.
00418         LSE_INLINE LSA_SIZE LSE_CALL CStdAllocatorHeap::GetHeapSize() const {
00419                 return m_sSize;
00420         }
00421 
00428         LSE_INLINE LSVOID LSE_CALL CStdAllocatorHeap::Set( LSVOID * _pvHeap, LSA_SIZE _sSizeOfHeap ) {
00429                 m_pvHeap = _pvHeap;
00430                 m_sSize = _sSizeOfHeap;
00431 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00432                 m_dInvSize = 1.0 / m_sSize;
00433 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00434                 //m_lpahAllocatedHead = NULL;
00435                 m_lpfhFreeHead = NULL;
00436                 m_psahNext = NULL;
00437                 for ( LSUINT32 I = 0; I < LSA_BUCKETS; ++I ) {
00438                         m_lpahAllocatedBlocks[I] = NULL;
00439                         m_lpfhFreeBlocks[I] = NULL;
00440                 }
00441 
00442                 m_usLowestFreeBlockInHashTable = LSA_BUCKETS - 1;
00443 
00444                 // Add the whole block to the free store.
00445                 AddFreeBlock( NULL, NULL, m_pvHeap, m_sSize );
00446         }
00447 
00448         // Given the address of a block, get the address returned to the user.
00449         LSE_INLINE LSVOID * CStdAllocatorHeap::GetStartAddress( const LPLSA_ALLOCATIONHEADER _lpahHeader ) {
00450                 LSA_SIZE sStart = reinterpret_cast<LSA_SIZE>(_lpahHeader);
00451 
00452                 // Skip the header.
00453                 sStart += sizeof( LSA_ALLOCATIONHEADER );
00454                 // From here, round up based on the alignment.
00455                 LSUINT32 ui32Align = LSA_MIN_ALIGN + LSA_MIN_ALIGN * _lpahHeader->ui32Alignment;
00456                 return reinterpret_cast<LSVOID *>(LSE_ROUND_UP( sStart, ui32Align ));
00457         }
00458 
00459         // Get the actual size of a block given the requested size, alignment, and start address.
00460         LSE_INLINE LSA_SIZE LSE_CALL CStdAllocatorHeap::GetActualSizeOfBlock( LSVOID * _pvAddr, LSA_SIZE _sSize, LSUINT32 _ui32Align ) {
00461                 LSA_SIZE sStart = reinterpret_cast<LSA_SIZE>(_pvAddr);
00462                 LSA_SIZE sOriginal = sStart;
00463                 // Skip the header.
00464                 sStart += sizeof( LSA_ALLOCATIONHEADER );
00465                 // From here, round up based on the alignment.
00466                 LSUINT32 ui32Align = LSA_MIN_ALIGN + LSA_MIN_ALIGN * _ui32Align;
00467 
00468                 sStart = LSE_ROUND_UP( sStart, ui32Align );
00469 
00470                 // Now add the requested allocation length.
00471                 sStart += _sSize;
00472 
00473                 sStart = LSE_ROUND_UP( sStart, LSA_MIN_ALIGN );
00474 
00475                 return sStart - sOriginal;
00476         }
00477 
00478         // Get the size of an allocated block.
00479         LSE_INLINE LSA_SIZE CStdAllocatorHeap::GetSize( const LPLSA_ALLOCATIONHEADER _lpahHeader ) {
00480                 return _lpahHeader->ui32Size * LSA_MIN_ALIGN;
00481         }
00482 
00483         // Given an address returned to the user, generate a hash key.
00484         LSE_INLINE LSUINT32 CStdAllocatorHeap::GetHashKey( LSVOID * _pvAddr ) const {
00485                 LSA_SUPERSIZE sStart = reinterpret_cast<LSA_SIZE>(_pvAddr);
00486                 LSA_SUPERSIZE sBase = reinterpret_cast<LSA_SIZE>(m_pvHeap);
00487                 sStart -= sBase;
00488 #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00489                 LSDOUBLE dFrac = sStart * m_dInvSize;
00490                 dFrac *= static_cast<LSDOUBLE>(1.5707963267948966192313216916398);
00491                 return static_cast<LSUINT32>(m_dSinTable[static_cast<LSUINT16>(1.0/(3.1415926535897932384626433832795*2.0)*0x10000*dFrac)] * (LSA_BUCKETS - 1));
00492 #else   // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00493                 sStart = sStart * LSA_BUCKETS / m_sSize;
00494                 return static_cast<LSUINT32>(sStart);
00495 #endif  // #ifdef LSA_USE_FLOAT_OPTIMIZATIONS
00496         }
00497 
00498         // Given a size, generate a hash key.
00499         LSE_INLINE LSUINT32 CStdAllocatorHeap::GetHashKey( LSA_SIZE _sSize ) {
00500                 _sSize >>= 12;
00501                 if ( _sSize < LSA_BUCKETS ) { return static_cast<LSUINT32>(_sSize); }
00502                 return LSA_BUCKETS - 1;
00503         }
00504 
00505         // Round up to the nearest alignment.
00506         LSE_INLINE LSA_SIZE LSE_CALL CStdAllocatorHeap::RoundUp( LSA_SIZE _sSize ) {
00507                 LSA_SIZE sThis = _sSize >> LSA_MIN_ALIGN_BITS;
00508                 if ( (_sSize & (LSA_MIN_ALIGN - 1)) ) {
00509                         return (sThis + 1) << LSA_MIN_ALIGN_BITS;
00510                 }
00511                 return sThis << LSA_MIN_ALIGN_BITS;
00512         }
00513 
00514         // Create a size key for allocation blocks.
00515         LSE_INLINE LSUINT32 LSE_CALL CStdAllocatorHeap::CreateSizeKey( LSA_SIZE _sSize ) {
00516                 LSA_SIZE sThis = _sSize >> LSA_MIN_ALIGN_BITS;
00517                 if ( (_sSize & (LSA_MIN_ALIGN - 1)) ) {
00518                         return static_cast<LSUINT32>(sThis + 1);
00519                 }
00520                 return static_cast<LSUINT32>(sThis);
00521                 //return static_cast<LSUINT32>(RoundUp( _sSize ) >> LSA_MIN_ALIGN_BITS);
00522         }
00523 
00524         // Get the alignment in decimal form given an alignment key.
00525         LSE_INLINE LSUINT32 LSE_CALL CStdAllocatorHeap::GetAlignment( LSUINT32 _ui32Key ) {
00526                 return LSA_MIN_ALIGN + LSA_MIN_ALIGN * _ui32Key;
00527         }
00528 
00529         // Get the head of the allocation list.
00530         LSE_INLINE CStdAllocatorHeap::LPLSA_ALLOCATIONHEADER LSE_CALL CStdAllocatorHeap::GetAllocationHead() const {
00531                 if ( m_lpfhFreeHead == m_pvHeap ) {
00532                         return GetNextAllocatedBlock( m_lpfhFreeHead );
00533                 }
00534                 return static_cast<LPLSA_ALLOCATIONHEADER>(m_pvHeap);
00535         }
00536 
00537         // Get the next allocated block after a free block or NULL if there are none.
00538         LSE_INLINE CStdAllocatorHeap::LPLSA_ALLOCATIONHEADER LSE_CALL CStdAllocatorHeap::GetNextAllocatedBlock( LPLSA_FREEHEADER _lpAfterMe ) const {
00539                 LSA_SIZE sStart = reinterpret_cast<LSA_SIZE>(_lpAfterMe);
00540                 sStart += _lpAfterMe->sActualSize;
00541                 LSA_SIZE sOurEnd = reinterpret_cast<LSA_SIZE>(m_pvHeap);
00542 
00543                 // If it points to the end of the block or beyond there is nothing there.
00544                 if ( sStart >= (sOurEnd + m_sSize) ) {
00545                         return NULL;
00546                 }
00547                 return reinterpret_cast<LPLSA_ALLOCATIONHEADER>(sStart);
00548         }
00549 
00550         // Get the next free block after the given allocated block, or NULL for none.
00551         LSE_INLINE CStdAllocatorHeap::LPLSA_FREEHEADER LSE_CALL CStdAllocatorHeap::GetNextFreeBlock( LPLSA_ALLOCATIONHEADER _lpahAfterMe ) {
00552                 // Go to the free block before this allocation.
00553                 LPLSA_FREEHEADER lpfhThis = _lpahAfterMe->pfhPrevFree;
00554                 if ( !lpfhThis ) {
00555                         return m_lpfhFreeHead;
00556                 }
00557                 // Return the next free block after that.
00558                 return lpfhThis->pfhNextFree;
00559         }
00560 
00561         // Fix up the free pointers on allocated blocks following a free block.
00562         LSE_INLINE LSVOID LSE_CALL CStdAllocatorHeap::FixUpAllocationFreeBlockPointers( LPLSA_FREEHEADER _lpfhAfterMe ) {
00563                 //LSA_SIZE sIamAt = reinterpret_cast<LSA_SIZE>(_lpfhAfterMe);
00564                 LSA_SIZE sEnd = reinterpret_cast<LSA_SIZE>(_lpfhAfterMe->pfhNextFree);
00565                 if ( !sEnd ) {
00566                         sEnd = static_cast<LSA_SIZE>(-1);
00567                 }
00568 
00569                 /*for ( LSUINT32 I = 0; I < LSA_BUCKETS; ++I ) {
00570                         for ( LPLSA_ALLOCATIONHEADER lpahThis = m_lpahAllocatedBlocks[I]; lpahThis; lpahThis = lpahThis->pahNextInHash ) {
00571                                 LSA_SIZE sThis = reinterpret_cast<LSA_SIZE>(lpahThis);
00572                                 if ( sThis > sIamAt && sThis < sEnd ) {
00573                                         lpahThis->pfhPrevFree = _lpfhAfterMe;
00574                                 }
00575                         }
00576                 }*/
00577 
00578 
00579                 LPLSA_ALLOCATIONHEADER lpahStart;
00580                 for ( lpahStart = GetNextAllocatedBlock( _lpfhAfterMe );
00581                         lpahStart;
00582                         lpahStart = lpahStart->pahNext ) {
00583                         LSA_SIZE sItPointsTo = reinterpret_cast<LSA_SIZE>(lpahStart->pfhPrevFree);
00584                         // If it points below us, we are the new closest.
00585                         // Make it point at us.
00586                         if ( sItPointsTo < sEnd ) {
00587                                 lpahStart->pfhPrevFree = _lpfhAfterMe;
00588                         }
00589                         else {
00590                                 break;
00591                         }
00592                 }
00593         }
00594 
00595         // In a linked-list of allocated blocks, replace each elementís previous free pointer with the one given
00596         //      if it matches the provided original free-block pointer.  Stops scanning at the first block that does
00597         //      not match the given key.
00598         LSE_INLINE LSVOID LSE_CALL CStdAllocatorHeap::ReplaceAllocationFreeBlockPointers( LPLSA_ALLOCATIONHEADER _lpahStart, LPLSA_FREEHEADER _lpfhReplaceMe, LPLSA_FREEHEADER _lpfhWithMe ) {
00599                 for ( ; _lpahStart; _lpahStart = _lpahStart->pahNext ) {
00600                         if ( _lpahStart->pfhPrevFree != _lpfhReplaceMe ) { return; }
00601                         _lpahStart->pfhPrevFree = _lpfhWithMe;
00602                 }
00603         }
00604 
00605         // Find an allocated block given its address.
00606         LSE_INLINE CStdAllocatorHeap::LPLSA_ALLOCATIONHEADER LSE_CALL CStdAllocatorHeap::FindAllocationBlock( LSVOID * _pvAddr ) {
00607                 LSUINT32 ui32Key = GetHashKey( _pvAddr );
00608                 // For every allocation in the hash table.
00609                 for ( LPLSA_ALLOCATIONHEADER lpahThis = m_lpahAllocatedBlocks[ui32Key]; lpahThis; lpahThis = lpahThis->pahNextInHash ) {
00610                         if ( GetStartAddress( lpahThis ) == _pvAddr ) {
00611                                 return lpahThis;
00612                         }
00613                 }
00614                 return NULL;
00615         }
00616 
00617 
00618 }       // namespace lsa
00619 
00620 #endif  // __LSA_STDALLOCATORHEAP_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator