/*
$Id: varalloc.cc,v 1.2 1996/10/11 09:10:26 roitzsch Exp $
(C)opyright 1996 by Konrad-Zuse-Center, Berlin
All rights reserved.
Part of the Kaskade distribution
*/
#include <iostream>
#include <stdlib.h>
#include "varalloc.h"
#include "utils.h"
//-------------------------------------------------------------------------
int VarSizeAllocator:: elemBaseSize = sizeof(int*); // for address alignment
//-------------------------------------------------------------------------
VarSizeAllocator:: VarSizeAllocator(int blockSize0) : blockSize(blockSize0)
{
if (blockSize <= 0)
{
cout << "\n*** class VarSizeAllocator: blockSize must be > 0"
<< " (read: " << blockSize << ")\n";
cout.flush(); abort();
}
while (blockSize % elemBaseSize != 0) ++blockSize;
lastBlock = 0;
noOfBlocks = 0;
noOfBlocksSinceIncrement = 0;
freeSpace = 0;
topOfBlock = 0;
memSpace = 0;
}
//-------------------------------------------------------------------------
VarSizeAllocator:: ~VarSizeAllocator()
{
MemoryBlock* toDel;
while(lastBlock)
{
toDel = lastBlock;
lastBlock = lastBlock->next;
::delete toDel->space;
::delete toDel;
}
}
//-------------------------------------------------------------------------
void VarSizeAllocator:: Info() const
{
cout << "\n\tVarSizeAllocator: " << noOfBlocks << " blocks ("
<< Form("%1.6f MB)\n", float(MemSpace())/1e6);
}
//-------------------------------------------------------------------------
void* VarSizeAllocator:: Get(int size)
{
char* returnSpace;
if (size > 1) while (size % elemBaseSize != 0) ++size;
while (size > blockSize) blockSize *= 2;
if (freeSpace+size > topOfBlock)
{
if (noOfBlocksSinceIncrement > 100) // dynamic size extension
{
blockSize *= 2;
noOfBlocksSinceIncrement = 0;
}
MemoryBlock* newBlock = new MemoryBlock;
if (newBlock == 0) allocationError();
newBlock->space = new char[blockSize];
if (newBlock->space == 0) allocationError();
newBlock->next = lastBlock;
lastBlock = newBlock;
++noOfBlocks;
++noOfBlocksSinceIncrement;
memSpace += blockSize + sizeof(MemoryBlock);
freeSpace = newBlock->space;
topOfBlock = freeSpace + blockSize;
}
returnSpace = freeSpace;
freeSpace += size;
return returnSpace;
}
//-------------------------------------------------------------------------
void VarSizeAllocator:: allocationError()
{
cout << "\n*** class VarSizeAllocator: could not allocate MemoryBlock\n";
cout.flush(); abort();
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
FixedSizeAllocator:: FixedSizeAllocator(int elementSize0,
int maxElementsInBlock0)
: elementSize(elementSize0), 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;
}
//-------------------------------------------------------------------------
int FixedSizeAllocator:: MemSpace() const
{
return memSpace + returnedElements.memSpace();
}
//-------------------------------------------------------------------------
void FixedSizeAllocator:: Info() const
{
cout << "\n\tFixedSizeAllocator: " << noOfBlocks << " blocks ("
<< Form("%1.6f MB)", float(MemSpace())/1e6)
<< " on stack: " << returnedElements.high() << "\n";
}
//-------------------------------------------------------------------------
void* FixedSizeAllocator:: getFromBlock()
{
++noOfElementsInBlock;
freeElement += elementSize;
if (noOfElementsInBlock > maxElementsInBlock)
{
if (noOfBlocksSinceIncrement > 100) // dynamic size extension
{
maxElementsInBlock *= 2;
noOfBlocksSinceIncrement = 0;
}
MemoryBlock* newBlock = ::new MemoryBlock;
if (newBlock == 0) allocationError();
newBlock->space = ::new char[elementSize*maxElementsInBlock];
if (newBlock->space == 0) allocationError();
newBlock->next = lastBlock;
lastBlock = newBlock;
++noOfBlocks;
++noOfBlocksSinceIncrement;
memSpace += maxElementsInBlock*elementSize + sizeof(MemoryBlock);
noOfElementsInBlock = 1;
freeElement = newBlock->space;
}
return freeElement;
}
//-------------------------------------------------------------------------
void FixedSizeAllocator:: allocationError()
{
cout << "\n*** Allocator: could not allocate MemoryBlock\n";
cout.flush(); abort();
}
//-------------------------------------------------------------------------
FixedSizeAllocator:: ~FixedSizeAllocator()
{
MemoryBlock* toDel;
while(lastBlock)
{
toDel = lastBlock;
lastBlock = lastBlock->next;
::delete [] toDel->space;
::delete toDel;
}
int i;
FORALL(returnedElements,i) returnedElements[i] = 0;
}
//-------------------------------------------------------------------------
void* FixedSizeAllocator:: Get()
{
void* elem;
if (returnedElements.h == 0) elem = getFromBlock();
else elem = returnedElements.pop();
return elem;
}
syntax highlighted by Code2HTML, v. 0.9.1