summaryrefslogtreecommitdiff
path: root/shared/loki/SmallObj.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/loki/SmallObj.cpp')
-rw-r--r--shared/loki/SmallObj.cpp582
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 )
{
bgstack15