summaryrefslogtreecommitdiff
path: root/utils/Allocator.cc
diff options
context:
space:
mode:
authorchatty1992-12-15 10:55:33 +0000
committerchatty1992-12-15 10:55:33 +0000
commit3a4838bed13b767132cbdf06364b2658da6cc356 (patch)
treef6d7b33264c4634d069409ba3169126823ac4090 /utils/Allocator.cc
parent23abb4b87c7e40ed259dd02f653516f60e55ade4 (diff)
downloadivy-league-3a4838bed13b767132cbdf06364b2658da6cc356.zip
ivy-league-3a4838bed13b767132cbdf06364b2658da6cc356.tar.gz
ivy-league-3a4838bed13b767132cbdf06364b2658da6cc356.tar.bz2
ivy-league-3a4838bed13b767132cbdf06364b2658da6cc356.tar.xz
Initial revision
Diffstat (limited to 'utils/Allocator.cc')
-rw-r--r--utils/Allocator.cc147
1 files changed, 147 insertions, 0 deletions
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 <stdlib.h>
+#include <unistd.h>
+#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
+}