diff options
Diffstat (limited to 'shared/loki/SmallObj.cpp')
-rw-r--r-- | shared/loki/SmallObj.cpp | 582 |
1 files changed, 291 insertions, 291 deletions
diff --git a/shared/loki/SmallObj.cpp b/shared/loki/SmallObj.cpp index adb54c55..0d82c1bb 100644 --- a/shared/loki/SmallObj.cpp +++ b/shared/loki/SmallObj.cpp @@ -28,274 +28,274 @@ //#define LOKI_CHECK_FOR_CORRUPTION #ifdef DO_EXTRA_LOKI_TESTS - #include <iostream> +#include <iostream> #endif namespace Loki { - /** @struct Chunk - @ingroup SmallObjectGroupInternal - Contains info about each allocated Chunk - which is a collection of - contiguous blocks. Each block is the same size, as specified by the - FixedAllocator. The number of blocks in a Chunk depends upon page size. - This is a POD-style struct with value-semantics. All functions and data - are private so that they can not be changed by anything other than the - FixedAllocator which owns the Chunk. - - @par Minimal Interface - For the sake of runtime efficiency, no constructor, destructor, or - copy-assignment operator is defined. The inline functions made by the - compiler should be sufficient, and perhaps faster than hand-crafted - functions. The lack of these functions allows vector to create and copy - Chunks as needed without overhead. The Init and Release functions do - what the default constructor and destructor would do. A Chunk is not in - a usable state after it is constructed and before calling Init. Nor is - a Chunk usable after Release is called, but before the destructor. - - @par Efficiency - Down near the lowest level of the allocator, runtime efficiencies trump - almost all other considerations. Each function does the minimum required - of it. All functions should execute in constant time to prevent higher- - level code from unwittingly using a version of Shlemiel the Painter's - Algorithm. - - @par Stealth Indexes - The first char of each empty block contains the index of the next empty - block. These stealth indexes form a singly-linked list within the blocks. - A Chunk is corrupt if this singly-linked list has a loop or is shorter - than blocksAvailable_. Much of the allocator's time and space efficiency - comes from how these stealth indexes are implemented. +/** @struct Chunk + @ingroup SmallObjectGroupInternal + Contains info about each allocated Chunk - which is a collection of + contiguous blocks. Each block is the same size, as specified by the + FixedAllocator. The number of blocks in a Chunk depends upon page size. + This is a POD-style struct with value-semantics. All functions and data + are private so that they can not be changed by anything other than the + FixedAllocator which owns the Chunk. + + @par Minimal Interface + For the sake of runtime efficiency, no constructor, destructor, or + copy-assignment operator is defined. The inline functions made by the + compiler should be sufficient, and perhaps faster than hand-crafted + functions. The lack of these functions allows vector to create and copy + Chunks as needed without overhead. The Init and Release functions do + what the default constructor and destructor would do. A Chunk is not in + a usable state after it is constructed and before calling Init. Nor is + a Chunk usable after Release is called, but before the destructor. + + @par Efficiency + Down near the lowest level of the allocator, runtime efficiencies trump + almost all other considerations. Each function does the minimum required + of it. All functions should execute in constant time to prevent higher- + level code from unwittingly using a version of Shlemiel the Painter's + Algorithm. + + @par Stealth Indexes + The first char of each empty block contains the index of the next empty + block. These stealth indexes form a singly-linked list within the blocks. + A Chunk is corrupt if this singly-linked list has a loop or is shorter + than blocksAvailable_. Much of the allocator's time and space efficiency + comes from how these stealth indexes are implemented. + */ +class Chunk +{ +private: + friend class FixedAllocator; + + /** Initializes a just-constructed Chunk. + @param blockSize Number of bytes per block. + @param blocks Number of blocks per Chunk. + @return True for success, false for failure. */ - class Chunk - { - private: - friend class FixedAllocator; + bool Init( std::size_t blockSize, unsigned char blocks ); - /** Initializes a just-constructed Chunk. - @param blockSize Number of bytes per block. - @param blocks Number of blocks per Chunk. - @return True for success, false for failure. - */ - bool Init( std::size_t blockSize, unsigned char blocks ); + /** Allocate a block within the Chunk. Complexity is always O(1), and + this will never throw. Does not actually "allocate" by calling + malloc, new, or any other function, but merely adjusts some internal + indexes to indicate an already allocated block is no longer available. + @return Pointer to block within Chunk. + */ + void* Allocate( std::size_t blockSize ); + + /** Deallocate a block within the Chunk. Complexity is always O(1), and + this will never throw. For efficiency, this assumes the address is + within the block and aligned along the correct byte boundary. An + assertion checks the alignment, and a call to HasBlock is done from + within VicinityFind. Does not actually "deallocate" by calling free, + delete, or other function, but merely adjusts some internal indexes to + indicate a block is now available. + */ + void Deallocate( void* p, std::size_t blockSize ); - /** Allocate a block within the Chunk. Complexity is always O(1), and - this will never throw. Does not actually "allocate" by calling - malloc, new, or any other function, but merely adjusts some internal - indexes to indicate an already allocated block is no longer available. - @return Pointer to block within Chunk. - */ - void * Allocate( std::size_t blockSize ); - - /** Deallocate a block within the Chunk. Complexity is always O(1), and - this will never throw. For efficiency, this assumes the address is - within the block and aligned along the correct byte boundary. An - assertion checks the alignment, and a call to HasBlock is done from - within VicinityFind. Does not actually "deallocate" by calling free, - delete, or other function, but merely adjusts some internal indexes to - indicate a block is now available. - */ - void Deallocate( void * p, std::size_t blockSize ); + /** Resets the Chunk back to pristine values. The available count is + set back to zero, and the first available index is set to the zeroth + block. The stealth indexes inside each block are set to point to the + next block. This assumes the Chunk's data was already using Init. + */ + void Reset( std::size_t blockSize, unsigned char blocks ); + + /// Releases the allocated block of memory. + void Release(); + + /** Determines if the Chunk has been corrupted. + @param numBlocks Total # of blocks in the Chunk. + @param blockSize # of bytes in each block. + @param checkIndexes True if caller wants to check indexes of available + blocks for corruption. If false, then caller wants to skip some + tests tests just to run faster. (Debug version does more checks, but + release version runs faster.) + @return True if Chunk is corrupt. + */ + bool IsCorrupt( unsigned char numBlocks, std::size_t blockSize, + bool checkIndexes ) const; + + /** Determines if block is available. + @param p Address of block managed by Chunk. + @param numBlocks Total # of blocks in the Chunk. + @param blockSize # of bytes in each block. + @return True if block is available, else false if allocated. + */ + bool IsBlockAvailable( void* p, unsigned char numBlocks, + std::size_t blockSize ) const; - /** Resets the Chunk back to pristine values. The available count is - set back to zero, and the first available index is set to the zeroth - block. The stealth indexes inside each block are set to point to the - next block. This assumes the Chunk's data was already using Init. - */ - void Reset( std::size_t blockSize, unsigned char blocks ); - - /// Releases the allocated block of memory. - void Release(); - - /** Determines if the Chunk has been corrupted. - @param numBlocks Total # of blocks in the Chunk. - @param blockSize # of bytes in each block. - @param checkIndexes True if caller wants to check indexes of available - blocks for corruption. If false, then caller wants to skip some - tests tests just to run faster. (Debug version does more checks, but - release version runs faster.) - @return True if Chunk is corrupt. - */ - bool IsCorrupt( unsigned char numBlocks, std::size_t blockSize, - bool checkIndexes ) const; - - /** Determines if block is available. - @param p Address of block managed by Chunk. - @param numBlocks Total # of blocks in the Chunk. - @param blockSize # of bytes in each block. - @return True if block is available, else false if allocated. - */ - bool IsBlockAvailable( void * p, unsigned char numBlocks, - std::size_t blockSize ) const; + /// Returns true if block at address P is inside this Chunk. + inline bool HasBlock( void* p, std::size_t chunkLength ) const + { + unsigned char* pc = static_cast< unsigned char* >( p ); + return ( pData_ <= pc ) && ( pc < pData_ + chunkLength ); + } - /// Returns true if block at address P is inside this Chunk. - inline bool HasBlock( void * p, std::size_t chunkLength ) const - { - unsigned char * pc = static_cast< unsigned char * >( p ); - return ( pData_ <= pc ) && ( pc < pData_ + chunkLength ); - } + inline bool HasAvailable( unsigned char numBlocks ) const + { return ( blocksAvailable_ == numBlocks ); } + + inline bool IsFilled( void ) const + { return ( 0 == blocksAvailable_ ); } + + /// Pointer to array of allocated blocks. + unsigned char* pData_; + /// Index of first empty block. + unsigned char firstAvailableBlock_; + /// Count of empty blocks. + unsigned char blocksAvailable_; +}; + +/** @class FixedAllocator + @ingroup SmallObjectGroupInternal + Offers services for allocating fixed-sized objects. It has a container + of "containers" of fixed-size blocks. The outer container has all the + Chunks. The inner container is a Chunk which owns some blocks. + + @par Class Level Invariants + - There is always either zero or one Chunk which is empty. + - If this has no empty Chunk, then emptyChunk_ is NULL. + - If this has an empty Chunk, then emptyChunk_ points to it. + - If the Chunk container is empty, then deallocChunk_ and allocChunk_ + are NULL. + - If the Chunk container is not-empty, then deallocChunk_ and allocChunk_ + are either NULL or point to Chunks within the container. + - allocChunk_ will often point to the last Chunk in the container since + it was likely allocated most recently, and therefore likely to have an + available block. + */ +class FixedAllocator +{ +private: - inline bool HasAvailable( unsigned char numBlocks ) const - { return ( blocksAvailable_ == numBlocks ); } - - inline bool IsFilled( void ) const - { return ( 0 == blocksAvailable_ ); } - - /// Pointer to array of allocated blocks. - unsigned char * pData_; - /// Index of first empty block. - unsigned char firstAvailableBlock_; - /// Count of empty blocks. - unsigned char blocksAvailable_; - }; - - /** @class FixedAllocator - @ingroup SmallObjectGroupInternal - Offers services for allocating fixed-sized objects. It has a container - of "containers" of fixed-size blocks. The outer container has all the - Chunks. The inner container is a Chunk which owns some blocks. - - @par Class Level Invariants - - There is always either zero or one Chunk which is empty. - - If this has no empty Chunk, then emptyChunk_ is NULL. - - If this has an empty Chunk, then emptyChunk_ points to it. - - If the Chunk container is empty, then deallocChunk_ and allocChunk_ - are NULL. - - If the Chunk container is not-empty, then deallocChunk_ and allocChunk_ - are either NULL or point to Chunks within the container. - - allocChunk_ will often point to the last Chunk in the container since - it was likely allocated most recently, and therefore likely to have an - available block. + /** Deallocates the block at address p, and then handles the internal + bookkeeping needed to maintain class invariants. This assumes that + deallocChunk_ points to the correct chunk. */ - class FixedAllocator - { - private: - - /** Deallocates the block at address p, and then handles the internal - bookkeeping needed to maintain class invariants. This assumes that - deallocChunk_ points to the correct chunk. - */ - void DoDeallocate( void * p ); + void DoDeallocate( void* p ); - /** Creates an empty Chunk and adds it to the end of the ChunkList. - All calls to the lower-level memory allocation functions occur inside - this function, and so the only try-catch block is inside here. - @return true for success, false for failure. - */ - bool MakeNewChunk( void ); - - /** Finds the Chunk which owns the block at address p. It starts at - deallocChunk_ and searches in both forwards and backwards directions - from there until it finds the Chunk which owns p. This algorithm - should find the Chunk quickly if it is deallocChunk_ or is close to it - in the Chunks container. This goes both forwards and backwards since - that works well for both same-order and opposite-order deallocations. - (Same-order = objects are deallocated in the same order in which they - were allocated. Opposite order = objects are deallocated in a last to - first order. Complexity is O(C) where C is count of all Chunks. This - never throws. - @return Pointer to Chunk that owns p, or NULL if no owner found. - */ - Chunk * VicinityFind( void * p ) const; - - /// Not implemented. - FixedAllocator(const FixedAllocator&); - /// Not implemented. - FixedAllocator& operator=(const FixedAllocator&); - - /// Type of container used to hold Chunks. - typedef std::vector< Chunk > Chunks; - /// Iterator through container of Chunks. - typedef Chunks::iterator ChunkIter; - /// Iterator through const container of Chunks. - typedef Chunks::const_iterator ChunkCIter; - - /// Fewest # of objects managed by a Chunk. - static unsigned char MinObjectsPerChunk_; - - /// Most # of objects managed by a Chunk - never exceeds UCHAR_MAX. - static unsigned char MaxObjectsPerChunk_; - - /// Number of bytes in a single block within a Chunk. - std::size_t blockSize_; - /// Number of blocks managed by each Chunk. - unsigned char numBlocks_; - - /// Container of Chunks. - Chunks chunks_; - /// Pointer to Chunk used for last or next allocation. - Chunk * allocChunk_; - /// Pointer to Chunk used for last or next deallocation. - Chunk * deallocChunk_; - /// Pointer to the only empty Chunk if there is one, else NULL. - Chunk * emptyChunk_; - - public: - /// Create a FixedAllocator which manages blocks of 'blockSize' size. - FixedAllocator(); - - /// Destroy the FixedAllocator and release all its Chunks. - ~FixedAllocator(); - - /// Initializes a FixedAllocator by calculating # of blocks per Chunk. - void Initialize( std::size_t blockSize, std::size_t pageSize ); - - /** Returns pointer to allocated memory block of fixed size - or NULL - if it failed to allocate. - */ - void * Allocate( void ); + /** Creates an empty Chunk and adds it to the end of the ChunkList. + All calls to the lower-level memory allocation functions occur inside + this function, and so the only try-catch block is inside here. + @return true for success, false for failure. + */ + bool MakeNewChunk( void ); + + /** Finds the Chunk which owns the block at address p. It starts at + deallocChunk_ and searches in both forwards and backwards directions + from there until it finds the Chunk which owns p. This algorithm + should find the Chunk quickly if it is deallocChunk_ or is close to it + in the Chunks container. This goes both forwards and backwards since + that works well for both same-order and opposite-order deallocations. + (Same-order = objects are deallocated in the same order in which they + were allocated. Opposite order = objects are deallocated in a last to + first order. Complexity is O(C) where C is count of all Chunks. This + never throws. + @return Pointer to Chunk that owns p, or NULL if no owner found. + */ + Chunk* VicinityFind( void* p ) const; + + /// Not implemented. + FixedAllocator(const FixedAllocator&); + /// Not implemented. + FixedAllocator& operator=(const FixedAllocator&); + + /// Type of container used to hold Chunks. + typedef std::vector< Chunk > Chunks; + /// Iterator through container of Chunks. + typedef Chunks::iterator ChunkIter; + /// Iterator through const container of Chunks. + typedef Chunks::const_iterator ChunkCIter; + + /// Fewest # of objects managed by a Chunk. + static unsigned char MinObjectsPerChunk_; + + /// Most # of objects managed by a Chunk - never exceeds UCHAR_MAX. + static unsigned char MaxObjectsPerChunk_; + + /// Number of bytes in a single block within a Chunk. + std::size_t blockSize_; + /// Number of blocks managed by each Chunk. + unsigned char numBlocks_; + + /// Container of Chunks. + Chunks chunks_; + /// Pointer to Chunk used for last or next allocation. + Chunk* allocChunk_; + /// Pointer to Chunk used for last or next deallocation. + Chunk* deallocChunk_; + /// Pointer to the only empty Chunk if there is one, else NULL. + Chunk* emptyChunk_; + +public: + /// Create a FixedAllocator which manages blocks of 'blockSize' size. + FixedAllocator(); + + /// Destroy the FixedAllocator and release all its Chunks. + ~FixedAllocator(); + + /// Initializes a FixedAllocator by calculating # of blocks per Chunk. + void Initialize( std::size_t blockSize, std::size_t pageSize ); + + /** Returns pointer to allocated memory block of fixed size - or NULL + if it failed to allocate. + */ + void* Allocate( void ); - /** Deallocate a memory block previously allocated with Allocate. If - the block is not owned by this FixedAllocator, it returns false so - that SmallObjAllocator can call the default deallocator. If the - block was found, this returns true. - */ - bool Deallocate( void * p, Chunk * hint ); + /** Deallocate a memory block previously allocated with Allocate. If + the block is not owned by this FixedAllocator, it returns false so + that SmallObjAllocator can call the default deallocator. If the + block was found, this returns true. + */ + bool Deallocate( void* p, Chunk* hint ); - /// Returns block size with which the FixedAllocator was initialized. - inline std::size_t BlockSize() const { return blockSize_; } + /// Returns block size with which the FixedAllocator was initialized. + inline std::size_t BlockSize() const { return blockSize_; } - /** Releases the memory used by the empty Chunk. This will take - constant time under any situation. - @return True if empty chunk found and released, false if none empty. - */ - bool TrimEmptyChunk( void ); + /** Releases the memory used by the empty Chunk. This will take + constant time under any situation. + @return True if empty chunk found and released, false if none empty. + */ + bool TrimEmptyChunk( void ); - /** Releases unused spots from ChunkList. This takes constant time - with respect to # of Chunks, but actual time depends on underlying - memory allocator. - @return False if no unused spots, true if some found and released. - */ - bool TrimChunkList( void ); + /** Releases unused spots from ChunkList. This takes constant time + with respect to # of Chunks, but actual time depends on underlying + memory allocator. + @return False if no unused spots, true if some found and released. + */ + bool TrimChunkList( void ); - /** Returns count of empty Chunks held by this allocator. Complexity - is O(C) where C is the total number of Chunks - empty or used. - */ - std::size_t CountEmptyChunks( void ) const; + /** Returns count of empty Chunks held by this allocator. Complexity + is O(C) where C is the total number of Chunks - empty or used. + */ + std::size_t CountEmptyChunks( void ) const; - /** Determines if FixedAllocator is corrupt. Checks data members to - see if any have erroneous values, or violate class invariants. It - also checks if any Chunk is corrupt. Complexity is O(C) where C is - the number of Chunks. If any data is corrupt, this will return true - in release mode, or assert in debug mode. - */ - bool IsCorrupt( void ) const; + /** Determines if FixedAllocator is corrupt. Checks data members to + see if any have erroneous values, or violate class invariants. It + also checks if any Chunk is corrupt. Complexity is O(C) where C is + the number of Chunks. If any data is corrupt, this will return true + in release mode, or assert in debug mode. + */ + bool IsCorrupt( void ) const; - /** Returns true if the block at address p is within a Chunk owned by - this FixedAllocator. Complexity is O(C) where C is the total number - of Chunks - empty or used. - */ - const Chunk * HasBlock( void * p ) const; - inline Chunk * HasBlock( void * p ) - { - return const_cast< Chunk * >( - const_cast< const FixedAllocator * >( this )->HasBlock( p ) ); - } + /** Returns true if the block at address p is within a Chunk owned by + this FixedAllocator. Complexity is O(C) where C is the total number + of Chunks - empty or used. + */ + const Chunk* HasBlock( void* p ) const; + inline Chunk* HasBlock( void* p ) + { + return const_cast< Chunk* >( + const_cast< const FixedAllocator* >( this )->HasBlock( p ) ); + } - }; +}; - unsigned char FixedAllocator::MinObjectsPerChunk_ = 8; - unsigned char FixedAllocator::MaxObjectsPerChunk_ = UCHAR_MAX; +unsigned char FixedAllocator::MinObjectsPerChunk_ = 8; +unsigned char FixedAllocator::MaxObjectsPerChunk_ = UCHAR_MAX; // Chunk::Init ---------------------------------------------------------------- @@ -310,11 +310,11 @@ bool Chunk::Init( std::size_t blockSize, unsigned char blocks ) #ifdef USE_NEW_TO_ALLOCATE // If this new operator fails, it will throw, and the exception will get // caught one layer up. - pData_ = static_cast< unsigned char * >( ::operator new ( allocSize ) ); + pData_ = static_cast< unsigned char* >( ::operator new ( allocSize ) ); #else // malloc can't throw, so its only way to indicate an error is to return // a NULL pointer, so we have to check for that. - pData_ = static_cast< unsigned char * >( ::std::malloc( allocSize ) ); + pData_ = static_cast< unsigned char* >( ::std::malloc( allocSize ) ); if ( NULL == pData_ ) return false; #endif @@ -335,7 +335,7 @@ void Chunk::Reset(std::size_t blockSize, unsigned char blocks) blocksAvailable_ = blocks; unsigned char i = 0; - for ( unsigned char * p = pData_; i != blocks; p += blockSize ) + for ( unsigned char* p = pData_; i != blocks; p += blockSize ) { *p = ++i; } @@ -349,7 +349,7 @@ void Chunk::Release() #ifdef USE_NEW_TO_ALLOCATE ::operator delete ( pData_ ); #else - ::std::free( static_cast< void * >( pData_ ) ); + ::std::free( static_cast< void* >( pData_ ) ); #endif } @@ -360,8 +360,8 @@ void* Chunk::Allocate(std::size_t blockSize) if ( IsFilled() ) return NULL; assert((firstAvailableBlock_ * blockSize) / blockSize == - firstAvailableBlock_); - unsigned char * pResult = pData_ + (firstAvailableBlock_ * blockSize); + firstAvailableBlock_); + unsigned char* pResult = pData_ + (firstAvailableBlock_ * blockSize); firstAvailableBlock_ = *pResult; --blocksAvailable_; @@ -378,7 +378,7 @@ void Chunk::Deallocate(void* p, std::size_t blockSize) // Alignment check assert((toRelease - pData_) % blockSize == 0); unsigned char index = static_cast< unsigned char >( - ( toRelease - pData_ ) / blockSize); + ( toRelease - pData_ ) / blockSize); #if defined(DEBUG) || defined(_DEBUG) // Check if block was already deleted. Attempting to delete the same @@ -399,7 +399,7 @@ void Chunk::Deallocate(void* p, std::size_t blockSize) // Chunk::IsCorrupt ----------------------------------------------------------- bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize, - bool checkIndexes ) const + bool checkIndexes ) const { if ( numBlocks < blocksAvailable_ ) @@ -428,7 +428,7 @@ bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize, found on the linked-list. */ std::bitset< UCHAR_MAX > foundBlocks; - unsigned char * nextBlock = NULL; + unsigned char* nextBlock = NULL; /* The loop goes along singly linked-list of stealth indexes and makes sure that each index is within bounds (0 <= index < numBlocks) and that the @@ -499,19 +499,19 @@ bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize, // Chunk::IsBlockAvailable ---------------------------------------------------- -bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks, - std::size_t blockSize ) const +bool Chunk::IsBlockAvailable( void* p, unsigned char numBlocks, + std::size_t blockSize ) const { (void) numBlocks; if ( IsFilled() ) return false; - unsigned char * place = static_cast< unsigned char * >( p ); + unsigned char* place = static_cast< unsigned char* >( p ); // Alignment check assert( ( place - pData_ ) % blockSize == 0 ); unsigned char blockIndex = static_cast< unsigned char >( - ( place - pData_ ) / blockSize ); + ( place - pData_ ) / blockSize ); unsigned char index = firstAvailableBlock_; assert( numBlocks > index ); @@ -522,7 +522,7 @@ bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks, found on the linked-list. */ std::bitset< UCHAR_MAX > foundBlocks; - unsigned char * nextBlock = NULL; + unsigned char* nextBlock = NULL; for ( unsigned char cc = 0; ; ) { nextBlock = pData_ + ( index * blockSize ); @@ -562,7 +562,7 @@ FixedAllocator::~FixedAllocator() assert( chunks_.empty() && "Memory leak detected!" ); #endif for ( ChunkIter i( chunks_.begin() ); i != chunks_.end(); ++i ) - i->Release(); + i->Release(); } // FixedAllocator::Initialize ------------------------------------------------- @@ -592,7 +592,7 @@ std::size_t FixedAllocator::CountEmptyChunks( void ) const std::size_t count = 0; for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it ) { - const Chunk & chunk = *it; + const Chunk& chunk = *it; if ( chunk.HasAvailable( numBlocks_ ) ) ++count; } @@ -642,8 +642,8 @@ bool FixedAllocator::IsCorrupt( void ) const else { - const Chunk * front = &chunks_.front(); - const Chunk * back = &chunks_.back(); + const Chunk* front = &chunks_.front(); + const Chunk* back = &chunks_.back(); if ( start >= last ) { assert( false ); @@ -708,7 +708,7 @@ bool FixedAllocator::IsCorrupt( void ) const } for ( ChunkCIter it( start ); it != last; ++it ) { - const Chunk & chunk = *it; + const Chunk& chunk = *it; if ( chunk.IsCorrupt( numBlocks_, blockSize_, true ) ) return true; } @@ -719,12 +719,12 @@ bool FixedAllocator::IsCorrupt( void ) const // FixedAllocator::HasBlock --------------------------------------------------- -const Chunk * FixedAllocator::HasBlock( void * p ) const +const Chunk* FixedAllocator::HasBlock( void* p ) const { const std::size_t chunkLength = numBlocks_ * blockSize_; for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it ) { - const Chunk & chunk = *it; + const Chunk& chunk = *it; if ( chunk.HasBlock( p, chunkLength ) ) return &chunk; } @@ -744,7 +744,7 @@ bool FixedAllocator::TrimEmptyChunk( void ) // And there should be exactly 1 empty Chunk. assert( 1 == CountEmptyChunks() ); - Chunk * lastChunk = &chunks_.back(); + Chunk* lastChunk = &chunks_.back(); if ( lastChunk != emptyChunk_ ) std::swap( *emptyChunk_, *lastChunk ); assert( lastChunk->HasAvailable( numBlocks_ ) ); @@ -828,7 +828,7 @@ bool FixedAllocator::MakeNewChunk( void ) // FixedAllocator::Allocate --------------------------------------------------- -void * FixedAllocator::Allocate( void ) +void* FixedAllocator::Allocate( void ) { // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); @@ -867,7 +867,7 @@ void * FixedAllocator::Allocate( void ) assert( allocChunk_ != NULL ); assert( !allocChunk_->IsFilled() ); - void * place = allocChunk_->Allocate( blockSize_ ); + void* place = allocChunk_->Allocate( blockSize_ ); // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); @@ -885,7 +885,7 @@ void * FixedAllocator::Allocate( void ) // FixedAllocator::Deallocate ------------------------------------------------- -bool FixedAllocator::Deallocate( void * p, Chunk * hint ) +bool FixedAllocator::Deallocate( void* p, Chunk* hint ) { assert(!chunks_.empty()); assert(&chunks_.front() <= deallocChunk_); @@ -894,7 +894,7 @@ bool FixedAllocator::Deallocate( void * p, Chunk * hint ) assert( &chunks_.back() >= allocChunk_ ); assert( CountEmptyChunks() < 2 ); - Chunk * foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint; + Chunk* foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint; if ( NULL == foundChunk ) return false; @@ -920,16 +920,16 @@ bool FixedAllocator::Deallocate( void * p, Chunk * hint ) // FixedAllocator::VicinityFind ----------------------------------------------- -Chunk * FixedAllocator::VicinityFind( void * p ) const +Chunk* FixedAllocator::VicinityFind( void* p ) const { if ( chunks_.empty() ) return NULL; assert(deallocChunk_); const std::size_t chunkLength = numBlocks_ * blockSize_; - Chunk * lo = deallocChunk_; - Chunk * hi = deallocChunk_ + 1; - const Chunk * loBound = &chunks_.front(); - const Chunk * hiBound = &chunks_.back() + 1; + Chunk* lo = deallocChunk_; + Chunk* hi = deallocChunk_ + 1; + const Chunk* loBound = &chunks_.front(); + const Chunk* hiBound = &chunks_.back() + 1; // Special case: deallocChunk_ is the last in the array if (hi == hiBound) hi = NULL; @@ -989,7 +989,7 @@ void FixedAllocator::DoDeallocate(void* p) // If last Chunk is empty, just change what deallocChunk_ // points to, and release the last. Otherwise, swap an empty // Chunk with the last, and then release it. - Chunk * lastChunk = &chunks_.back(); + Chunk* lastChunk = &chunks_.back(); if ( lastChunk == deallocChunk_ ) deallocChunk_ = emptyChunk_; else if ( lastChunk != emptyChunk_ ) @@ -1025,13 +1025,13 @@ inline std::size_t GetOffset( std::size_t numBytes, std::size_t alignment ) @param doThrow True if this function should throw an exception, or false if it should indicate failure by returning a NULL pointer. */ -void * DefaultAllocator( std::size_t numBytes, bool doThrow ) +void* DefaultAllocator( std::size_t numBytes, bool doThrow ) { #ifdef USE_NEW_TO_ALLOCATE return doThrow ? ::operator new( numBytes ) : - ::operator new( numBytes, std::nothrow_t() ); + ::operator new( numBytes, std::nothrow_t() ); #else - void * p = ::std::malloc( numBytes ); + void* p = ::std::malloc( numBytes ); if ( doThrow && ( NULL == p ) ) throw std::bad_alloc(); return p; @@ -1046,7 +1046,7 @@ void * DefaultAllocator( std::size_t numBytes, bool doThrow ) it matches malloc which is the preferred default allocator. SmallObjAllocator will call this if an address was not found among any of its own blocks. */ -void DefaultDeallocator( void * p ) +void DefaultDeallocator( void* p ) { #ifdef USE_NEW_TO_ALLOCATE ::operator delete( p ); @@ -1058,7 +1058,7 @@ void DefaultDeallocator( void * p ) // SmallObjAllocator::SmallObjAllocator --------------------------------------- SmallObjAllocator::SmallObjAllocator( std::size_t pageSize, - std::size_t maxObjectSize, std::size_t objectAlignSize ) : + std::size_t maxObjectSize, std::size_t objectAlignSize ) : pool_( NULL ), maxSmallObjectSize_( maxObjectSize ), objectAlignSize_( objectAlignSize ) @@ -1106,7 +1106,7 @@ bool SmallObjAllocator::TrimExcessMemory( void ) // SmallObjAllocator::Allocate ------------------------------------------------ -void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) +void* SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) { if ( numBytes > GetMaxObjectSize() ) return DefaultAllocator( numBytes, doThrow ); @@ -1118,10 +1118,10 @@ void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) (void) allocCount; assert( index < allocCount ); - FixedAllocator & allocator = pool_[ index ]; + FixedAllocator& allocator = pool_[ index ]; assert( allocator.BlockSize() >= numBytes ); assert( allocator.BlockSize() < numBytes + GetAlignment() ); - void * place = allocator.Allocate(); + void* place = allocator.Allocate(); if ( ( NULL == place ) && TrimExcessMemory() ) place = allocator.Allocate(); @@ -1141,7 +1141,7 @@ void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) // SmallObjAllocator::Deallocate ---------------------------------------------- -void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes ) +void SmallObjAllocator::Deallocate( void* p, std::size_t numBytes ) { if ( NULL == p ) return; if ( numBytes > GetMaxObjectSize() ) @@ -1155,7 +1155,7 @@ void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes ) const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); (void) allocCount; assert( index < allocCount ); - FixedAllocator & allocator = pool_[ index ]; + FixedAllocator& allocator = pool_[ index ]; assert( allocator.BlockSize() >= numBytes ); assert( allocator.BlockSize() < numBytes + GetAlignment() ); const bool found = allocator.Deallocate( p, NULL ); @@ -1165,13 +1165,13 @@ void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes ) // SmallObjAllocator::Deallocate ---------------------------------------------- -void SmallObjAllocator::Deallocate( void * p ) +void SmallObjAllocator::Deallocate( void* p ) { if ( NULL == p ) return; assert( NULL != pool_ ); - FixedAllocator * pAllocator = NULL; + FixedAllocator* pAllocator = NULL; const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); - Chunk * chunk = NULL; + Chunk* chunk = NULL; for ( std::size_t ii = 0; ii < allocCount; ++ii ) { |