/*
$Id: alloc.c,v 1.1 1996/10/10 10:01:08 roitzsch Exp $
(C)opyright 1996 by Konrad-Zuse-Center, Berlin
All rights reserved.
Part of the Kaskade distribution
*/
#include "utils.h"
#include "alloc.h"
template<class T> StaticAllocator<T>:: StaticAllocator(int maxElementsInBlock0)
: returnedElements(1,10)
{
if (maxElementsInBlock0 < 1)
{
cout << "\n*** Allocator: maxElementsInBlock must be > 1\n"
<< "\t (read: " << maxElementsInBlock << ")\n";
cout.flush(); abort();
}
maxElementsInBlock = maxElementsInBlock0;
noOfElementsInBlock = maxElementsInBlock0;
lastBlock = 0;
noOfBlocks = 0;
freeElement = 0;
noOfBlocksSinceIncrement = 0;
memSpace = 0;
}
//-------------------------------------------------------------------------
template<class T> int StaticAllocator<T>:: MemSpace() const
{
return memSpace + returnedElements.memSpace();
}
//-------------------------------------------------------------------------
template<class T> void StaticAllocator<T>:: Info() const
{
cout << "\n\tAllocator: " << noOfBlocks << " blocks ("
<< Form("%1.6f MB)", float(MemSpace())/1e6)
<< " on stack: " << returnedElements.high() << "\n";
}
//-------------------------------------------------------------------------
template<class T> T* StaticAllocator<T>:: Get()
{
T* elem;
if (returnedElements.h == 0) elem = getFromBlock();
else elem = returnedElements.pop();
return elem;
}
//-------------------------------------------------------------------------
template<class T> T* StaticAllocator<T>:: getFromBlock()
{
++noOfElementsInBlock;
++freeElement;
if (noOfElementsInBlock > maxElementsInBlock)
{
if (noOfBlocksSinceIncrement > 100) // dynamic size extension
{
maxElementsInBlock *= 2;
noOfBlocksSinceIncrement = 0;
}
MemoryBlock* newBlock = ::new MemoryBlock;
if (newBlock == 0) allocationError();
newBlock->space = ::new T[maxElementsInBlock];
if (newBlock->space == 0) allocationError();
newBlock->next = lastBlock;
lastBlock = newBlock;
++noOfBlocks;
++noOfBlocksSinceIncrement;
memSpace += maxElementsInBlock*sizeof(T) + sizeof(MemoryBlock);
noOfElementsInBlock = 1;
freeElement = newBlock->space;
}
return freeElement;
}
//-------------------------------------------------------------------------
template<class T> void StaticAllocator<T>:: allocationError()
{
cout << "\n*** Allocator: could not allocate MemoryBlock\n";
cout.flush(); abort();
}
//-------------------------------------------------------------------------
template<class T> Allocator<T>:: ~Allocator()
{
typename StaticAllocator<T>::MemoryBlock* toDel;
while(this->lastBlock)
{
toDel = this->lastBlock;
this->lastBlock = this->lastBlock->next;
delete [] toDel->space;
delete toDel;
}
int i;
FORALL(this->returnedElements,i) this->returnedElements[i] = 0;
}
//-------------------------------------------------------------------------
template<class T> T* Allocator<T>:: Get()
{
T* elem;
if (this->returnedElements.h == 0) elem = this->getFromBlock();
else
{
elem = this->returnedElements.pop();
elem->reset();
}
return elem;
}
syntax highlighted by Code2HTML, v. 0.9.1