/* $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 #include #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; }