void * FixedAllocator::Allocate( void ) { // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); assert( CountEmptyChunks() < 2 ); if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() ) { if ( NULL != emptyChunk_ ) { allocChunk_ = emptyChunk_; emptyChunk_ = NULL; } else { for ( ChunkIter i( chunks_.begin() ); ; ++i ) { if ( chunks_.end() == i ) { if ( !MakeNewChunk() ) return NULL; break; } if ( !i->IsFilled() ) { allocChunk_ = &*i; break; } } } } else if ( allocChunk_ == emptyChunk_) // detach emptyChunk_ from allocChunk_, because after // calling allocChunk_->Allocate(blockSize_); the chunk // is no longer empty. emptyChunk_ = NULL; assert( allocChunk_ != NULL ); 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( CountEmptyChunks() < 2 ); #ifdef LOKI_CHECK_FOR_CORRUPTION if ( allocChunk_->IsCorrupt( numBlocks_, blockSize_, true ) ) { assert( false ); return NULL; } #endif return place; }
void * FixedAllocator::Allocate( void ) { // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); if ( ( NULL == allocChunk_ ) || allocChunk_->IsFilled() ) { if ( NULL != emptyChunk_ ) { allocChunk_ = emptyChunk_; emptyChunk_ = NULL; } else { for ( ChunkIter i( chunks_.begin() ); ; ++i ) { if ( chunks_.end() == i ) { if ( !MakeNewChunk() ) return NULL; break; } if ( !i->IsFilled() ) { allocChunk_ = &*i; break; } } } } assert( allocChunk_ != NULL ); assert( !allocChunk_->IsFilled() ); // prove either emptyChunk_ points nowhere, or points to a truly empty Chunk. assert( ( NULL == emptyChunk_ ) || ( emptyChunk_->HasAvailable( numBlocks_ ) ) ); return allocChunk_->Allocate(blockSize_); }