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