From 3a4838bed13b767132cbdf06364b2658da6cc356 Mon Sep 17 00:00:00 2001 From: chatty Date: Tue, 15 Dec 1992 10:55:33 +0000 Subject: Initial revision --- utils/Allocator.cc | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 utils/Allocator.cc (limited to 'utils/Allocator.cc') diff --git a/utils/Allocator.cc b/utils/Allocator.cc new file mode 100644 index 0000000..d89ebf6 --- /dev/null +++ b/utils/Allocator.cc @@ -0,0 +1,147 @@ +/* + * CENA C++ Utilities + * + * by Stephane Chatty + * + * Copyright 1992 + * Centre d'Etudes de la Navigation Aerienne (CENA) + * + * Memory allocation (original C version by Michel Beaudouin-Lafon) + * + * $Id$ + * $CurLog$ + */ + +#include "Allocator.h" +#include +#include +#include "Signal.h" + +/*?class CcuAllocator +The memory manager is implemented through a C++ class called \typ{CcuAllocator}. +Each instance of this class is a memory allocator, which delivers memory blocks of +a given size. + +Allocators work as follow: each allocator obtains pages of memory through \fun{malloc}. +It then splits that memory in blocks in order to deliver them. When a block is freed, it +is stored in a list of free blocks so as to be reused. In the current implementation, +memory pages are never released. +?*/ + + +#define CHUNKSIZE 1024 + +/* + * Supposing that memory blocks must always be aligned on + * word boundaries, we allocate chunks as arrays of words, + * and express all sizes in words. + * + */ +#ifndef WORD_TYPE +#define WORD_TYPE int +#endif + +typedef WORD_TYPE Word; + +inline unsigned int +SizeInWords (unsigned int size) +{ + return (size + sizeof (Word) -1) / sizeof (Word); +} + +/*? +This function is called when there is no more memory. It issues an error message to +the standard error output, then calls \fun{exit}. +?*/ +void +CcuAllocator :: MemoryOverflow () +{ + static char msg [] = "Memory overflow. Bye ...\n"; + + write (2, msg, sizeof (msg)); + exit (99); +} + +/*? +Constructor for \typ{CcuAllocator}s. It initializes an allocator for structures of size \var{size}. +For implementation reasons, allocated blocks will be at least the size of a pointer. +?*/ +CcuAllocator :: CcuAllocator (unsigned int size) +: BlockSize (SizeInWords (size)), + ChunkSize (SizeInWords (CHUNKSIZE)), + FreeList (0), + AllocEnd (0), + AllocNext (0) +{ + /* if blocks are too small to hold a pointer, enlarge them */ + unsigned int ptr_size = SizeInWords (sizeof (Word*)); + if (BlockSize < ptr_size) + BlockSize = ptr_size; + + /* if chunks are too small to hold two blocks, enlarge them */ + if (ChunkSize < 2*BlockSize) + ChunkSize = 2*BlockSize; +} + +/*?nodoc?*/ +CcuAllocator :: ~CcuAllocator () +{ +} + +/*? +Allocate a block of memory with an \typ{CcuAllocator}. +This function returns the address of the allocated block, or 0 if the allocation failed +for some reason. +The allocated block is aligned on a word boundary, and it is {\em not} filled with zeroes. +?*/ +void* +CcuAllocator :: Alloc () +{ +#ifdef MEMORY_DEBUG + CcuSignalBlocker b (AllSigs); + void* w = new Word [BlockSize]; + return w; +#else + register Word* block; + + /* give memory from the free-list */ + if (FreeList) { + block = (Word*) FreeList; + FreeList = ((Word**) FreeList)[0]; + /* or from fresh memory */ + } else { + block = (Word*) AllocNext; + AllocNext = ((Word*) AllocNext) + BlockSize; + if (AllocNext > AllocEnd) { + /* here we have to get new chunk */ + CcuSignalBlocker b (AllSigs); + block = new Word [ChunkSize]; + if (block == 0) + MemoryOverflow (); + /* we suppose we can put at least 2 objects in a chunk */ + AllocNext = block + BlockSize; + AllocEnd = block + ChunkSize; + } + } + return block; +#endif +} + + +/*? +Free the memory allocated at \var{p} by this \typ{CcuAllocator}. +No check is performed, and you should take care that \var{p} +was allocated by this allocator. +?*/ +void +CcuAllocator :: Free (void* p) +{ +#ifdef MEMORY_DEBUG + CcuSignalBlocker b (AllSigs); + delete [] ((Word*) p); +#else + /* Prepend the block to the list of free blocks */ + ((Word**) p)[0] = (Word*) FreeList; + FreeList = p; +#endif +} -- cgit v1.1