/* $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 StaticAllocator:: 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 int StaticAllocator:: MemSpace() const { return memSpace + returnedElements.memSpace(); } //------------------------------------------------------------------------- template void StaticAllocator:: Info() const { cout << "\n\tAllocator: " << noOfBlocks << " blocks (" << Form("%1.6f MB)", float(MemSpace())/1e6) << " on stack: " << returnedElements.high() << "\n"; } //------------------------------------------------------------------------- template T* StaticAllocator:: Get() { T* elem; if (returnedElements.h == 0) elem = getFromBlock(); else elem = returnedElements.pop(); return elem; } //------------------------------------------------------------------------- template T* StaticAllocator:: 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 void StaticAllocator:: allocationError() { cout << "\n*** Allocator: could not allocate MemoryBlock\n"; cout.flush(); abort(); } //------------------------------------------------------------------------- template Allocator:: ~Allocator() { typename StaticAllocator::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 T* Allocator:: Get() { T* elem; if (this->returnedElements.h == 0) elem = this->getFromBlock(); else { elem = this->returnedElements.pop(); elem->reset(); } return elem; }