CVC3

memory_manager_chunks.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file memory_manager_chunks.h
00004  * 
00005  * Author: Sergey Berezin
00006  * 
00007  * Created: Tue Apr 19 14:30:36 2005
00008  *
00009  * <hr>
00010  *
00011  * License to use, copy, modify, sell and/or distribute this software
00012  * and its documentation for any purpose is hereby granted without
00013  * royalty, subject to the terms and conditions defined in the \ref
00014  * LICENSE file provided with this distribution.
00015  * 
00016  * <hr>
00017  * 
00018  * Class MemoryManager: allocates/deallocates memory for objects of a
00019  * fixed size (the size is a parameter to the constructor).  The
00020  * actual memory is allocated in big chunks, which (at the moment) are
00021  * never released back.  However, the deallocated blocks are later reused.
00022  * 
00023  * Typical use of this class is to create 
00024  * MemoryManager* mm = new MemoryManager(sizeof(YourClass)); 
00025  * where YourClass has operators new and delete redefined:
00026  * void* YourClass::operator new(size_t, MemoryManager* mm)
00027  * { return mm->newData(); }
00028  * void YourClass::delete(void*) { } // do not deallocate memory here
00029  * Then, create objects with obj = new(mm) YourClass(), and destroy them with
00030  * delete obj; mm->deleteData(obj);
00031  */
00032 /*****************************************************************************/
00033 
00034 #ifndef _cvc3__memory_manager_chunks_h
00035 #define _cvc3__memory_manager_chunks_h
00036 
00037 #include <vector>
00038 #include "memory_manager.h"
00039 
00040 namespace CVC3 {
00041 
00042 class MemoryManagerChunks: public MemoryManager {
00043  private:
00044   unsigned d_dataSize; // #bytes in each data element
00045   unsigned d_chunkSize; // number of data elements
00046   unsigned d_chunkSizeBytes; // #bytes in each chunk
00047   std::vector<char*> d_freeList;
00048   std::vector<char*> d_chunkList; // Pointers to the beginning of each chunk
00049   // Pointer to the next free block of memory in the current chunk
00050   char* d_nextFree;
00051   // End of current chunk (1 byte off the end)
00052   char* d_endChunk;
00053 
00054   // Private methods
00055   void newChunk() { // Allocate new chunk
00056     d_nextFree = (char*)malloc(d_chunkSizeBytes);
00057     FatalAssert(d_nextFree != NULL, "Out of memory");
00058     d_endChunk = d_nextFree + d_chunkSizeBytes;
00059     d_chunkList.push_back(d_nextFree);
00060   }
00061 
00062  public:
00063   // Constructor
00064   MemoryManagerChunks(unsigned dataSize, unsigned chunkSize = 1024)
00065     : d_dataSize(dataSize), d_chunkSize(chunkSize),
00066       d_chunkSizeBytes(dataSize*chunkSize),
00067       d_nextFree(NULL), d_endChunk(NULL) { }
00068   // Destructor
00069   ~MemoryManagerChunks() {
00070     while(d_chunkList.size() > 0) {
00071       free(d_chunkList.back());
00072       d_chunkList.pop_back();
00073     }
00074   }
00075 
00076   void* newData(size_t size) {
00077     DebugAssert(size == d_dataSize,
00078     "MemoryManager::newData: the data size doesn't match");
00079     void* res;
00080     // Check the free list first
00081     if(d_freeList.size() > 0) {
00082       res = (void*)d_freeList.back();
00083       d_freeList.pop_back();
00084       return res;
00085     }
00086     if(d_nextFree == NULL || d_nextFree == d_endChunk)
00087       newChunk();
00088     res = (void*)d_nextFree;
00089     d_nextFree += d_dataSize;
00090     return res;
00091   }
00092 
00093   void deleteData(void* d) {
00094     d_freeList.push_back((char*)d);
00095   }
00096 }; // end of class MemoryManager
00097 
00098 }
00099 
00100 #endif