|
From: <ric...@us...> - 2010-03-15 06:03:07
|
Revision: 1068
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1068&view=rev
Author: rich_sposato
Date: 2010-03-15 06:03:01 +0000 (Mon, 15 Mar 2010)
Log Message:
-----------
Fixed bug using patch by ryants.
Modified Paths:
--------------
trunk/src/SmallObj.cpp
Modified: trunk/src/SmallObj.cpp
===================================================================
--- trunk/src/SmallObj.cpp 2009-12-22 11:36:36 UTC (rev 1067)
+++ trunk/src/SmallObj.cpp 2010-03-15 06:03:01 UTC (rev 1068)
@@ -790,6 +790,8 @@
return false;
// Use the "make-a-temp-and-swap" trick to remove excess capacity.
Chunks( chunks_ ).swap( chunks_ );
+ deallocChunk_ = &chunks_.front();
+ allocChunk_ = &chunks_.back();
return true;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2010-09-08 00:48:35
|
Revision: 1070
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1070&view=rev
Author: rich_sposato
Date: 2010-09-08 00:48:29 +0000 (Wed, 08 Sep 2010)
Log Message:
-----------
Replaced NULL with nullptr.
Modified Paths:
--------------
trunk/src/SmallObj.cpp
Modified: trunk/src/SmallObj.cpp
===================================================================
--- trunk/src/SmallObj.cpp 2010-04-19 03:09:59 UTC (rev 1069)
+++ trunk/src/SmallObj.cpp 2010-09-08 00:48:29 UTC (rev 1070)
@@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author or Addison-Wesley Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author or Addison-Wesley Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
@@ -31,6 +31,11 @@
#include <iostream>
#endif
+#if !defined( nullptr )
+ #define nullptr
+#endif
+
+
namespace Loki
{
@@ -157,12 +162,12 @@
@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 no empty Chunk, then emptyChunk_ is nullptr.
- If this has an empty Chunk, then emptyChunk_ points to it.
- If the Chunk container is empty, then deallocChunk_ and allocChunk_
- are NULL.
+ are nullptr.
- If the Chunk container is not-empty, then deallocChunk_ and allocChunk_
- are either NULL or point to Chunks within the container.
+ are either nullptr 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.
@@ -194,7 +199,7 @@
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.
+ @return Pointer to Chunk that owns p, or nullptr if no owner found.
*/
Chunk * VicinityFind( void * p ) const;
@@ -227,7 +232,7 @@
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.
+ /// Pointer to the only empty Chunk if there is one, else nullptr.
Chunk * emptyChunk_;
public:
@@ -240,7 +245,7 @@
/// 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
+ /** Returns pointer to allocated memory block of fixed size - or nullptr
if it failed to allocate.
*/
void * Allocate( void );
@@ -313,9 +318,9 @@
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.
+ // a nullptr pointer, so we have to check for that.
pData_ = static_cast< unsigned char * >( ::std::malloc( allocSize ) );
- if ( NULL == pData_ ) return false;
+ if ( nullptr == pData_ ) return false;
#endif
Reset( blockSize, blocks );
@@ -345,7 +350,7 @@
void Chunk::Release()
{
- assert( NULL != pData_ );
+ assert( nullptr != pData_ );
#ifdef USE_NEW_TO_ALLOCATE
::operator delete ( pData_ );
#else
@@ -357,9 +362,9 @@
void* Chunk::Allocate(std::size_t blockSize)
{
- if ( IsFilled() ) return NULL;
+ if ( IsFilled() ) return nullptr;
- assert((firstAvailableBlock_ * blockSize) / blockSize ==
+ assert((firstAvailableBlock_ * blockSize) / blockSize ==
firstAvailableBlock_);
unsigned char * pResult = pData_ + (firstAvailableBlock_ * blockSize);
firstAvailableBlock_ = *pResult;
@@ -428,7 +433,7 @@
found on the linked-list.
*/
std::bitset< UCHAR_MAX > foundBlocks;
- unsigned char * nextBlock = NULL;
+ unsigned char * nextBlock = nullptr;
/* 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
@@ -503,7 +508,7 @@
std::size_t blockSize ) const
{
(void) numBlocks;
-
+
if ( IsFilled() )
return false;
@@ -522,7 +527,7 @@
found on the linked-list.
*/
std::bitset< UCHAR_MAX > foundBlocks;
- unsigned char * nextBlock = NULL;
+ unsigned char * nextBlock = nullptr;
for ( unsigned char cc = 0; ; )
{
nextBlock = pData_ + ( index * blockSize );
@@ -547,9 +552,9 @@
: blockSize_( 0 )
, numBlocks_( 0 )
, chunks_( 0 )
- , allocChunk_( NULL )
- , deallocChunk_( NULL )
- , emptyChunk_( NULL )
+ , allocChunk_( nullptr )
+ , deallocChunk_( nullptr )
+ , emptyChunk_( nullptr )
{
}
@@ -598,7 +603,7 @@
}
return count;
#else
- return ( NULL == emptyChunk_ ) ? 0 : 1;
+ return ( nullptr == emptyChunk_ ) ? 0 : 1;
#endif
}
@@ -623,17 +628,17 @@
assert( false );
return true;
}
- if ( NULL != deallocChunk_ )
+ if ( nullptr != deallocChunk_ )
{
assert( false );
return true;
}
- if ( NULL != allocChunk_ )
+ if ( nullptr != allocChunk_ )
{
assert( false );
return true;
}
- if ( NULL != emptyChunk_ )
+ if ( nullptr != emptyChunk_ )
{
assert( false );
return true;
@@ -673,14 +678,14 @@
switch ( emptyChunkCount )
{
case 0:
- if ( emptyChunk_ != NULL )
+ if ( emptyChunk_ != nullptr )
{
assert( false );
return true;
}
break;
case 1:
- if ( emptyChunk_ == NULL )
+ if ( emptyChunk_ == nullptr )
{
assert( false );
return true;
@@ -728,7 +733,7 @@
if ( chunk.HasBlock( p, chunkLength ) )
return &chunk;
}
- return NULL;
+ return nullptr;
}
// FixedAllocator::TrimEmptyChunk ---------------------------------------------
@@ -736,8 +741,8 @@
bool FixedAllocator::TrimEmptyChunk( void )
{
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
- assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
- if ( NULL == emptyChunk_ ) return false;
+ assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
+ if ( nullptr == emptyChunk_ ) return false;
// If emptyChunk_ points to valid Chunk, then chunk list is not empty.
assert( !chunks_.empty() );
@@ -753,8 +758,8 @@
if ( chunks_.empty() )
{
- allocChunk_ = NULL;
- deallocChunk_ = NULL;
+ allocChunk_ = nullptr;
+ deallocChunk_ = nullptr;
}
else
{
@@ -770,7 +775,7 @@
}
}
- emptyChunk_ = NULL;
+ emptyChunk_ = nullptr;
assert( 0 == CountEmptyChunks() );
return true;
@@ -782,8 +787,8 @@
{
if ( chunks_.empty() )
{
- assert( NULL == allocChunk_ );
- assert( NULL == deallocChunk_ );
+ assert( nullptr == allocChunk_ );
+ assert( nullptr == deallocChunk_ );
}
if ( chunks_.size() == chunks_.capacity() )
@@ -833,15 +838,15 @@
void * FixedAllocator::Allocate( void )
{
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
- assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
+ assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
assert( CountEmptyChunks() < 2 );
- if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() )
+ if ( ( nullptr == allocChunk_ ) || allocChunk_->IsFilled() )
{
- if ( NULL != emptyChunk_ )
+ if ( nullptr != emptyChunk_ )
{
allocChunk_ = emptyChunk_;
- emptyChunk_ = NULL;
+ emptyChunk_ = nullptr;
}
else
{
@@ -850,7 +855,7 @@
if ( chunks_.end() == i )
{
if ( !MakeNewChunk() )
- return NULL;
+ return nullptr;
break;
}
if ( !i->IsFilled() )
@@ -862,23 +867,23 @@
}
}
else if ( allocChunk_ == emptyChunk_)
- // detach emptyChunk_ from allocChunk_, because after
- // calling allocChunk_->Allocate(blockSize_); the chunk
+ // detach emptyChunk_ from allocChunk_, because after
+ // calling allocChunk_->Allocate(blockSize_); the chunk
// is no longer empty.
- emptyChunk_ = NULL;
+ emptyChunk_ = nullptr;
- assert( allocChunk_ != NULL );
+ assert( allocChunk_ != nullptr );
assert( !allocChunk_->IsFilled() );
void * place = allocChunk_->Allocate( blockSize_ );
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
- assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
+ assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
assert( CountEmptyChunks() < 2 );
#ifdef LOKI_CHECK_FOR_CORRUPTION
if ( allocChunk_->IsCorrupt( numBlocks_, blockSize_, true ) )
{
assert( false );
- return NULL;
+ return nullptr;
}
#endif
@@ -896,8 +901,8 @@
assert( &chunks_.back() >= allocChunk_ );
assert( CountEmptyChunks() < 2 );
- Chunk * foundChunk = ( NULL == hint ) ? VicinityFind( p ) : hint;
- if ( NULL == foundChunk )
+ Chunk * foundChunk = ( nullptr == hint ) ? VicinityFind( p ) : hint;
+ if ( nullptr == foundChunk )
return false;
assert( foundChunk->HasBlock( p, numBlocks_ * blockSize_ ) );
@@ -924,7 +929,7 @@
Chunk * FixedAllocator::VicinityFind( void * p ) const
{
- if ( chunks_.empty() ) return NULL;
+ if ( chunks_.empty() ) return nullptr;
assert(deallocChunk_);
const std::size_t chunkLength = numBlocks_ * blockSize_;
@@ -934,7 +939,7 @@
const Chunk * hiBound = &chunks_.back() + 1;
// Special case: deallocChunk_ is the last in the array
- if (hi == hiBound) hi = NULL;
+ if (hi == hiBound) hi = nullptr;
for (;;)
{
@@ -943,8 +948,8 @@
if ( lo->HasBlock( p, chunkLength ) ) return lo;
if ( lo == loBound )
{
- lo = NULL;
- if ( NULL == hi ) break;
+ lo = nullptr;
+ if ( nullptr == hi ) break;
}
else --lo;
}
@@ -954,13 +959,13 @@
if ( hi->HasBlock( p, chunkLength ) ) return hi;
if ( ++hi == hiBound )
{
- hi = NULL;
- if ( NULL == lo ) break;
+ hi = nullptr;
+ if ( nullptr == lo ) break;
}
}
}
- return NULL;
+ return nullptr;
}
// FixedAllocator::DoDeallocate -----------------------------------------------
@@ -974,7 +979,7 @@
assert( emptyChunk_ != deallocChunk_ );
assert( !deallocChunk_->HasAvailable( numBlocks_ ) );
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
- assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
+ assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
// call into the chunk, will adjust the inner list but won't release memory
deallocChunk_->Deallocate(p, blockSize_);
@@ -986,7 +991,7 @@
// empty chunks. Since emptyChunk_ may only point to a previously
// cleared Chunk, if it points to something else besides deallocChunk_,
// then FixedAllocator currently has 2 empty Chunks.
- if ( NULL != emptyChunk_ )
+ if ( nullptr != emptyChunk_ )
{
// If last Chunk is empty, just change what deallocChunk_
// points to, and release the last. Otherwise, swap an empty
@@ -999,14 +1004,14 @@
assert( lastChunk->HasAvailable( numBlocks_ ) );
lastChunk->Release();
chunks_.pop_back();
- if ( ( allocChunk_ == lastChunk ) || allocChunk_->IsFilled() )
+ if ( ( allocChunk_ == lastChunk ) || allocChunk_->IsFilled() )
allocChunk_ = deallocChunk_;
}
emptyChunk_ = deallocChunk_;
}
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
- assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
+ assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
}
// GetOffset ------------------------------------------------------------------
@@ -1025,7 +1030,7 @@
the size which can be handled by any FixedAllocator.
@param numBytes number of bytes
@param doThrow True if this function should throw an exception, or false if it
- should indicate failure by returning a NULL pointer.
+ should indicate failure by returning a nullptr pointer.
*/
void * DefaultAllocator( std::size_t numBytes, bool doThrow )
{
@@ -1034,7 +1039,7 @@
::operator new( numBytes, std::nothrow_t() );
#else
void * p = ::std::malloc( numBytes );
- if ( doThrow && ( NULL == p ) )
+ if ( doThrow && ( nullptr == p ) )
throw std::bad_alloc();
return p;
#endif
@@ -1042,7 +1047,7 @@
// DefaultDeallocator ---------------------------------------------------------
/** @ingroup SmallObjectGroupInternal
- Calls default deallocator when SmallObjAllocator decides not to handle a
+ Calls default deallocator when SmallObjAllocator decides not to handle a
request. The default deallocator could be the global delete operator or the
free function. The free function is the preferred default deallocator since
it matches malloc which is the preferred default allocator. SmallObjAllocator
@@ -1061,7 +1066,7 @@
SmallObjAllocator::SmallObjAllocator( std::size_t pageSize,
std::size_t maxObjectSize, std::size_t objectAlignSize ) :
- pool_( NULL ),
+ pool_( nullptr ),
maxSmallObjectSize_( maxObjectSize ),
objectAlignSize_( objectAlignSize )
{
@@ -1113,7 +1118,7 @@
if ( numBytes > GetMaxObjectSize() )
return DefaultAllocator( numBytes, doThrow );
- assert( NULL != pool_ );
+ assert( nullptr != pool_ );
if ( 0 == numBytes ) numBytes = 1;
const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
@@ -1125,10 +1130,10 @@
assert( allocator.BlockSize() < numBytes + GetAlignment() );
void * place = allocator.Allocate();
- if ( ( NULL == place ) && TrimExcessMemory() )
+ if ( ( nullptr == place ) && TrimExcessMemory() )
place = allocator.Allocate();
- if ( ( NULL == place ) && doThrow )
+ if ( ( nullptr == place ) && doThrow )
{
#ifdef _MSC_VER
throw std::bad_alloc( "could not allocate small object" );
@@ -1145,13 +1150,13 @@
void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes )
{
- if ( NULL == p ) return;
+ if ( nullptr == p ) return;
if ( numBytes > GetMaxObjectSize() )
{
DefaultDeallocator( p );
return;
}
- assert( NULL != pool_ );
+ assert( nullptr != pool_ );
if ( 0 == numBytes ) numBytes = 1;
const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
@@ -1160,7 +1165,7 @@
FixedAllocator & allocator = pool_[ index ];
assert( allocator.BlockSize() >= numBytes );
assert( allocator.BlockSize() < numBytes + GetAlignment() );
- const bool found = allocator.Deallocate( p, NULL );
+ const bool found = allocator.Deallocate( p, nullptr );
(void) found;
assert( found );
}
@@ -1169,28 +1174,28 @@
void SmallObjAllocator::Deallocate( void * p )
{
- if ( NULL == p ) return;
- assert( NULL != pool_ );
- FixedAllocator * pAllocator = NULL;
+ if ( nullptr == p ) return;
+ assert( nullptr != pool_ );
+ FixedAllocator * pAllocator = nullptr;
const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
- Chunk * chunk = NULL;
+ Chunk * chunk = nullptr;
for ( std::size_t ii = 0; ii < allocCount; ++ii )
{
chunk = pool_[ ii ].HasBlock( p );
- if ( NULL != chunk )
+ if ( nullptr != chunk )
{
pAllocator = &pool_[ ii ];
break;
}
}
- if ( NULL == pAllocator )
+ if ( nullptr == pAllocator )
{
DefaultDeallocator( p );
return;
}
- assert( NULL != chunk );
+ assert( nullptr != chunk );
const bool found = pAllocator->Deallocate( p, chunk );
(void) found;
assert( found );
@@ -1200,7 +1205,7 @@
bool SmallObjAllocator::IsCorrupt( void ) const
{
- if ( NULL == pool_ )
+ if ( nullptr == pool_ )
{
assert( false );
return true;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2010-09-08 01:58:57
|
Revision: 1072
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1072&view=rev
Author: rich_sposato
Date: 2010-09-08 01:58:51 +0000 (Wed, 08 Sep 2010)
Log Message:
-----------
Some coding style changes. Added namespace resolution.
Modified Paths:
--------------
trunk/src/SmallObj.cpp
Modified: trunk/src/SmallObj.cpp
===================================================================
--- trunk/src/SmallObj.cpp 2010-09-08 01:03:21 UTC (rev 1071)
+++ trunk/src/SmallObj.cpp 2010-09-08 01:58:51 UTC (rev 1072)
@@ -87,7 +87,7 @@
@param blocks Number of blocks per Chunk.
@return True for success, false for failure.
*/
- bool Init( std::size_t blockSize, unsigned char blocks );
+ 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
@@ -95,7 +95,7 @@
indexes to indicate an already allocated block is no longer available.
@return Pointer to block within Chunk.
*/
- void * Allocate( std::size_t blockSize );
+ 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
@@ -105,14 +105,14 @@
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 );
+ 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 );
+ void Reset( ::std::size_t blockSize, unsigned char blocks );
/// Releases the allocated block of memory.
void Release();
@@ -126,7 +126,7 @@
release version runs faster.)
@return True if Chunk is corrupt.
*/
- bool IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
+ bool IsCorrupt( unsigned char numBlocks, ::std::size_t blockSize,
bool checkIndexes ) const;
/** Determines if block is available.
@@ -136,10 +136,10 @@
@return True if block is available, else false if allocated.
*/
bool IsBlockAvailable( void * p, unsigned char numBlocks,
- std::size_t blockSize ) const;
+ ::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
+ inline bool HasBlock( void * p, ::std::size_t chunkLength ) const
{
unsigned char * pc = static_cast< unsigned char * >( p );
return ( pData_ <= pc ) && ( pc < pData_ + chunkLength );
@@ -214,7 +214,7 @@
FixedAllocator& operator=(const FixedAllocator&);
/// Type of container used to hold Chunks.
- typedef std::vector< Chunk > Chunks;
+ typedef ::std::vector< Chunk > Chunks;
/// Iterator through container of Chunks.
typedef Chunks::iterator ChunkIter;
/// Iterator through const container of Chunks.
@@ -227,7 +227,7 @@
static unsigned char MaxObjectsPerChunk_;
/// Number of bytes in a single block within a Chunk.
- std::size_t blockSize_;
+ ::std::size_t blockSize_;
/// Number of blocks managed by each Chunk.
unsigned char numBlocks_;
@@ -248,7 +248,7 @@
~FixedAllocator();
/// Initializes a FixedAllocator by calculating # of blocks per Chunk.
- void Initialize( std::size_t blockSize, std::size_t pageSize );
+ void Initialize( ::std::size_t blockSize, ::std::size_t pageSize );
/** Returns pointer to allocated memory block of fixed size - or nullptr
if it failed to allocate.
@@ -263,7 +263,7 @@
bool Deallocate( void * p, Chunk * hint );
/// Returns block size with which the FixedAllocator was initialized.
- inline std::size_t BlockSize() const { return blockSize_; }
+ inline ::std::size_t BlockSize() const { return blockSize_; }
/** Releases the memory used by the empty Chunk. This will take
constant time under any situation.
@@ -281,7 +281,7 @@
/** 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;
+ ::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
@@ -315,7 +315,7 @@
@param doThrow True if this function should throw an exception, or false if it
should indicate failure by returning a nullptr pointer.
*/
-void * DefaultAllocator( std::size_t numBytes, bool doThrow );
+void * DefaultAllocator( ::std::size_t numBytes, bool doThrow );
/** @ingroup SmallObjectGroupInternal
Calls default deallocator when SmallObjAllocator decides not to handle a
@@ -329,12 +329,12 @@
// Chunk::Init ----------------------------------------------------------------
-bool Chunk::Init( std::size_t blockSize, unsigned char blocks )
+bool Chunk::Init( ::std::size_t blockSize, unsigned char blocks )
{
assert(blockSize > 0);
assert(blocks > 0);
// Overflow check
- const std::size_t allocSize = blockSize * blocks;
+ const ::std::size_t allocSize = blockSize * blocks;
assert( allocSize / blockSize == blocks);
#ifdef USE_NEW_TO_ALLOCATE
@@ -345,7 +345,8 @@
// malloc can't throw, so its only way to indicate an error is to return
// a nullptr pointer, so we have to check for that.
pData_ = static_cast< unsigned char * >( ::std::malloc( allocSize ) );
- if ( nullptr == pData_ ) return false;
+ if ( nullptr == pData_ )
+ return false;
#endif
Reset( blockSize, blocks );
@@ -354,7 +355,7 @@
// Chunk::Reset ---------------------------------------------------------------
-void Chunk::Reset(std::size_t blockSize, unsigned char blocks)
+void Chunk::Reset(::std::size_t blockSize, unsigned char blocks)
{
assert(blockSize > 0);
assert(blocks > 0);
@@ -385,9 +386,10 @@
// Chunk::Allocate ------------------------------------------------------------
-void* Chunk::Allocate(std::size_t blockSize)
+void* Chunk::Allocate(::std::size_t blockSize)
{
- if ( IsFilled() ) return nullptr;
+ if ( IsFilled() )
+ return nullptr;
assert((firstAvailableBlock_ * blockSize) / blockSize ==
firstAvailableBlock_);
@@ -400,7 +402,7 @@
// Chunk::Deallocate ----------------------------------------------------------
-void Chunk::Deallocate(void* p, std::size_t blockSize)
+void Chunk::Deallocate(void* p, ::std::size_t blockSize)
{
assert(p >= pData_);
@@ -428,7 +430,7 @@
// Chunk::IsCorrupt -----------------------------------------------------------
-bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize,
+bool Chunk::IsCorrupt( unsigned char numBlocks, ::std::size_t blockSize,
bool checkIndexes ) const
{
@@ -457,7 +459,7 @@
/* If the bit at index was set in foundBlocks, then the stealth index was
found on the linked-list.
*/
- std::bitset< UCHAR_MAX > foundBlocks;
+ ::std::bitset< UCHAR_MAX > foundBlocks;
unsigned char * nextBlock = nullptr;
/* The loop goes along singly linked-list of stealth indexes and makes sure
@@ -530,7 +532,7 @@
// Chunk::IsBlockAvailable ----------------------------------------------------
bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks,
- std::size_t blockSize ) const
+ ::std::size_t blockSize ) const
{
(void) numBlocks;
@@ -551,7 +553,7 @@
/* If the bit at index was set in foundBlocks, then the stealth index was
found on the linked-list.
*/
- std::bitset< UCHAR_MAX > foundBlocks;
+ ::std::bitset< UCHAR_MAX > foundBlocks;
unsigned char * nextBlock = nullptr;
for ( unsigned char cc = 0; ; )
{
@@ -597,13 +599,13 @@
// FixedAllocator::Initialize -------------------------------------------------
-void FixedAllocator::Initialize( std::size_t blockSize, std::size_t pageSize )
+void FixedAllocator::Initialize( ::std::size_t blockSize, ::std::size_t pageSize )
{
assert( blockSize > 0 );
assert( pageSize >= blockSize );
blockSize_ = blockSize;
- std::size_t numBlocks = pageSize / blockSize;
+ ::std::size_t numBlocks = pageSize / blockSize;
if ( numBlocks > MaxObjectsPerChunk_ ) numBlocks = MaxObjectsPerChunk_;
else if ( numBlocks < MinObjectsPerChunk_ ) numBlocks = MinObjectsPerChunk_;
@@ -613,13 +615,13 @@
// FixedAllocator::CountEmptyChunks -------------------------------------------
-std::size_t FixedAllocator::CountEmptyChunks( void ) const
+::std::size_t FixedAllocator::CountEmptyChunks( void ) const
{
#ifdef DO_EXTRA_LOKI_TESTS
// This code is only used for specialized tests of the allocator.
// It is #ifdef-ed so that its O(C) complexity does not overwhelm the
// functions which call it.
- std::size_t count = 0;
+ ::std::size_t count = 0;
for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it )
{
const Chunk & chunk = *it;
@@ -639,7 +641,7 @@
const bool isEmpty = chunks_.empty();
ChunkCIter start( chunks_.begin() );
ChunkCIter last( chunks_.end() );
- const size_t emptyChunkCount = CountEmptyChunks();
+ const ::std::size_t emptyChunkCount = CountEmptyChunks();
if ( isEmpty )
{
@@ -751,7 +753,7 @@
const Chunk * FixedAllocator::HasBlock( void * p ) const
{
- const std::size_t chunkLength = numBlocks_ * blockSize_;
+ const ::std::size_t chunkLength = numBlocks_ * blockSize_;
for ( ChunkCIter it( chunks_.begin() ); it != chunks_.end(); ++it )
{
const Chunk & chunk = *it;
@@ -767,7 +769,8 @@
{
// prove either emptyChunk_ points nowhere, or points to a truly empty Chunk.
assert( ( nullptr == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) );
- if ( nullptr == emptyChunk_ ) return false;
+ if ( nullptr == emptyChunk_ )
+ return false;
// If emptyChunk_ points to valid Chunk, then chunk list is not empty.
assert( !chunks_.empty() );
@@ -776,7 +779,7 @@
Chunk * lastChunk = &chunks_.back();
if ( lastChunk != emptyChunk_ )
- std::swap( *emptyChunk_, *lastChunk );
+ ::std::swap( *emptyChunk_, *lastChunk );
assert( lastChunk->HasAvailable( numBlocks_ ) );
lastChunk->Release();
chunks_.pop_back();
@@ -833,7 +836,7 @@
bool allocated = false;
try
{
- std::size_t size = chunks_.size();
+ ::std::size_t size = chunks_.size();
// Calling chunks_.reserve *before* creating and initializing the new
// Chunk means that nothing is leaked by this function in case an
// exception is thrown from reserve.
@@ -954,38 +957,44 @@
Chunk * FixedAllocator::VicinityFind( void * p ) const
{
- if ( chunks_.empty() ) return nullptr;
+ if ( chunks_.empty() )
+ return nullptr;
assert(deallocChunk_);
- const std::size_t chunkLength = numBlocks_ * blockSize_;
+ 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;
// Special case: deallocChunk_ is the last in the array
- if (hi == hiBound) hi = nullptr;
+ if ( hi == hiBound )
+ hi = nullptr;
for (;;)
{
if (lo)
{
- if ( lo->HasBlock( p, chunkLength ) ) return lo;
+ if ( lo->HasBlock( p, chunkLength ) )
+ return lo;
if ( lo == loBound )
{
lo = nullptr;
- if ( nullptr == hi ) break;
+ if ( nullptr == hi )
+ break;
}
else --lo;
}
if (hi)
{
- if ( hi->HasBlock( p, chunkLength ) ) return hi;
+ if ( hi->HasBlock( p, chunkLength ) )
+ return hi;
if ( ++hi == hiBound )
{
hi = nullptr;
- if ( nullptr == lo ) break;
+ if ( nullptr == lo )
+ break;
}
}
}
@@ -1025,7 +1034,7 @@
if ( lastChunk == deallocChunk_ )
deallocChunk_ = emptyChunk_;
else if ( lastChunk != emptyChunk_ )
- std::swap( *emptyChunk_, *lastChunk );
+ ::std::swap( *emptyChunk_, *lastChunk );
assert( lastChunk->HasAvailable( numBlocks_ ) );
lastChunk->Release();
chunks_.pop_back();
@@ -1042,15 +1051,15 @@
// GetOffset ------------------------------------------------------------------
/// @ingroup SmallObjectGroupInternal
/// Calculates index into array where a FixedAllocator of numBytes is located.
-inline std::size_t GetOffset( std::size_t numBytes, std::size_t alignment )
+inline ::std::size_t GetOffset( ::std::size_t numBytes, ::std::size_t alignment )
{
- const std::size_t alignExtra = alignment-1;
+ const ::std::size_t alignExtra = alignment-1;
return ( numBytes + alignExtra ) / alignment;
}
// DefaultAllocator -----------------------------------------------------------
-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 ) :
@@ -1083,8 +1092,8 @@
// SmallObjAllocator::SmallObjAllocator ---------------------------------------
-SmallObjAllocator::SmallObjAllocator( std::size_t pageSize,
- std::size_t maxObjectSize, std::size_t objectAlignSize ) :
+SmallObjAllocator::SmallObjAllocator( ::std::size_t pageSize,
+ ::std::size_t maxObjectSize, ::std::size_t objectAlignSize ) :
pool_( nullptr ),
maxSmallObjectSize_( maxObjectSize ),
objectAlignSize_( objectAlignSize )
@@ -1093,9 +1102,9 @@
std::cout << "SmallObjAllocator " << this << std::endl;
#endif
assert( 0 != objectAlignSize );
- const std::size_t allocCount = GetOffset( maxObjectSize, objectAlignSize );
+ const ::std::size_t allocCount = GetOffset( maxObjectSize, objectAlignSize );
pool_ = new FixedAllocator[ allocCount ];
- for ( std::size_t i = 0; i < allocCount; ++i )
+ for ( ::std::size_t i = 0; i < allocCount; ++i )
pool_[ i ].Initialize( ( i+1 ) * objectAlignSize, pageSize );
}
@@ -1114,8 +1123,8 @@
bool SmallObjAllocator::TrimExcessMemory( void )
{
bool found = false;
- const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
- std::size_t i = 0;
+ const ::std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
+ ::std::size_t i = 0;
for ( ; i < allocCount; ++i )
{
if ( pool_[ i ].TrimEmptyChunk() )
@@ -1132,15 +1141,15 @@
// 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 );
assert( nullptr != pool_ );
if ( 0 == numBytes ) numBytes = 1;
- const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
- const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
+ const ::std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
+ const ::std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
(void) allocCount;
assert( index < allocCount );
@@ -1167,9 +1176,10 @@
// SmallObjAllocator::Deallocate ----------------------------------------------
-void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes )
+void SmallObjAllocator::Deallocate( void * p, ::std::size_t numBytes )
{
- if ( nullptr == p ) return;
+ if ( nullptr == p )
+ return;
if ( numBytes > GetMaxObjectSize() )
{
DefaultDeallocator( p );
@@ -1177,8 +1187,8 @@
}
assert( nullptr != pool_ );
if ( 0 == numBytes ) numBytes = 1;
- const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
- const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
+ const ::std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
+ const ::std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
(void) allocCount;
assert( index < allocCount );
FixedAllocator & allocator = pool_[ index ];
@@ -1193,13 +1203,14 @@
void SmallObjAllocator::Deallocate( void * p )
{
- if ( nullptr == p ) return;
+ if ( nullptr == p )
+ return;
assert( nullptr != pool_ );
- ::Loki::Private::FixedAllocator * pAllocator = nullptr;
- const std::size_t allocCount = ::Loki::Private::GetOffset( GetMaxObjectSize(), GetAlignment() );
+ FixedAllocator * pAllocator = nullptr;
+ const ::std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
Chunk * chunk = nullptr;
- for ( std::size_t ii = 0; ii < allocCount; ++ii )
+ for ( ::std::size_t ii = 0; ii < allocCount; ++ii )
{
chunk = pool_[ ii ].HasBlock( p );
if ( nullptr != chunk )
@@ -1239,8 +1250,8 @@
assert( false );
return true;
}
- const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
- for ( std::size_t ii = 0; ii < allocCount; ++ii )
+ const ::std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
+ for ( ::std::size_t ii = 0; ii < allocCount; ++ii )
{
if ( pool_[ ii ].IsCorrupt() )
return true;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2010-09-08 02:22:34
|
Revision: 1073
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1073&view=rev
Author: rich_sposato
Date: 2010-09-08 02:22:28 +0000 (Wed, 08 Sep 2010)
Log Message:
-----------
Fixed bug 3061653 by adding code to check pointers to chunks before searching. Fixed bug 3061659 by checking for empty list.
Modified Paths:
--------------
trunk/src/SmallObj.cpp
Modified: trunk/src/SmallObj.cpp
===================================================================
--- trunk/src/SmallObj.cpp 2010-09-08 01:58:51 UTC (rev 1072)
+++ trunk/src/SmallObj.cpp 2010-09-08 02:22:28 UTC (rev 1073)
@@ -821,11 +821,24 @@
if ( chunks_.size() == chunks_.capacity() )
return false;
- // Use the "make-a-temp-and-swap" trick to remove excess capacity.
- Chunks( chunks_ ).swap( chunks_ );
- deallocChunk_ = &chunks_.front();
- allocChunk_ = &chunks_.back();
+ {
+ // Use the "make-a-temp-and-swap" trick to remove excess capacity.
+ Chunks temp( chunks_ );
+ temp.swap( chunks_ );
+ }
+
+ if ( chunks_.empty() )
+ {
+ deallocChunk_ = nullptr;
+ allocChunk_ = nullptr;
+ }
+ else
+ {
+ deallocChunk_ = &chunks_.front();
+ allocChunk_ = &chunks_.back();
+ }
+
return true;
}
@@ -929,7 +942,15 @@
assert( &chunks_.back() >= allocChunk_ );
assert( CountEmptyChunks() < 2 );
- Chunk * foundChunk = ( nullptr == hint ) ? VicinityFind( p ) : hint;
+ Chunk * foundChunk = nullptr;
+ if ( ( nullptr != hint ) && ( hint->HasBlock( p, numBlocks_ * blockSize_ ) ) )
+ foundChunk = hint;
+ else if ( deallocChunk_->HasBlock( p, numBlocks_ * blockSize_ ) )
+ foundChunk = deallocChunk_;
+ else if ( allocChunk_->HasBlock( p, numBlocks_ * blockSize_ ) )
+ foundChunk = allocChunk_;
+ else
+ foundChunk = VicinityFind( p );
if ( nullptr == foundChunk )
return false;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2010-09-16 17:24:05
|
Revision: 1075
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1075&view=rev
Author: rich_sposato
Date: 2010-09-16 17:23:59 +0000 (Thu, 16 Sep 2010)
Log Message:
-----------
Replaced repeated calculation with local variable.
Modified Paths:
--------------
trunk/src/SmallObj.cpp
Modified: trunk/src/SmallObj.cpp
===================================================================
--- trunk/src/SmallObj.cpp 2010-09-16 17:22:53 UTC (rev 1074)
+++ trunk/src/SmallObj.cpp 2010-09-16 17:23:59 UTC (rev 1075)
@@ -943,18 +943,19 @@
assert( CountEmptyChunks() < 2 );
Chunk * foundChunk = nullptr;
- if ( ( nullptr != hint ) && ( hint->HasBlock( p, numBlocks_ * blockSize_ ) ) )
+ const ::std::size_t chunkLength = numBlocks_ * blockSize_;
+ if ( ( nullptr != hint ) && ( hint->HasBlock( p, chunkLength ) ) )
foundChunk = hint;
- else if ( deallocChunk_->HasBlock( p, numBlocks_ * blockSize_ ) )
+ else if ( deallocChunk_->HasBlock( p, chunkLength ) )
foundChunk = deallocChunk_;
- else if ( allocChunk_->HasBlock( p, numBlocks_ * blockSize_ ) )
+ else if ( allocChunk_->HasBlock( p, chunkLength ) )
foundChunk = allocChunk_;
else
foundChunk = VicinityFind( p );
if ( nullptr == foundChunk )
return false;
- assert( foundChunk->HasBlock( p, numBlocks_ * blockSize_ ) );
+ assert( foundChunk->HasBlock( p, chunkLength ) );
#ifdef LOKI_CHECK_FOR_CORRUPTION
if ( foundChunk->IsCorrupt( numBlocks_, blockSize_, true ) )
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|