MemoryPool.inl
Go to the documentation of this file.00001 //*** MemoryPool.inl *** 00002 00003 #include "StandardLibrary.h" 00004 #include "Debug.h" 00005 00006 #include <new> 00007 00008 //*** Constructor *** 00009 00010 template<class TYPE> 00011 MemoryPool<TYPE>::MemoryPool(int entriesPerBlock): 00012 entriesPerBlock_(entriesPerBlock), 00013 usedEntriesCount_(0), 00014 entries_(0), 00015 entriesSize_(0), 00016 entriesCount_(0), 00017 blocks_(0), 00018 blocksSize_(0), 00019 blocksCount_(0) 00020 { 00021 } 00022 00023 00024 //*** Destructor *** 00025 00026 template<class TYPE> 00027 MemoryPool<TYPE>::~MemoryPool() 00028 { 00029 if (entries_) 00030 { 00031 delete[] entries_; 00032 } 00033 00034 if (blocks_) 00035 { 00036 // Loop through and free the blocks. 00037 for (int i=0; i<blocksCount_; i++) 00038 { 00039 ::Free(blocks_[i]); 00040 } 00041 00042 ::Free(blocks_); 00043 } 00044 } 00045 00046 00047 //*** CreateBlock *** 00048 00049 template<class TYPE> 00050 void MemoryPool<TYPE>::CreateBlock() 00051 { 00052 // If no block array have been allocated yet, allocate it now 00053 if (!blocks_) 00054 { 00055 blocksSize_=16; 00056 blocks_=static_cast<TYPE**>(Malloc(sizeof(TYPE*)*blocksSize_)); 00057 Assert(blocks_,"Couldn't allocate a memory block for the MemoryPool"); 00058 if (!blocks_) 00059 { 00060 FatalError("Allocation failed when allocating memory for memory pool"); 00061 } 00062 } 00063 00064 // If the blocks array is full, double it and reallocate it 00065 if (blocksCount_>=blocksSize_) 00066 { 00067 blocksSize_*=2; 00068 blocks_=static_cast<TYPE**>(Realloc(blocks_,sizeof(TYPE*)*blocksSize_)); 00069 Assert(blocks_,"Couldn't allocate a memory block for the MemoryPool"); 00070 if (!blocks_) 00071 { 00072 FatalError("Allocation failed when allocating memory for memory pool"); 00073 } 00074 } 00075 00076 // Allocate a block of memory. 00077 TYPE* newBlock = static_cast<TYPE*>(Malloc(sizeof(TYPE)*entriesPerBlock_)); 00078 Assert(newBlock,"Couldn't allocate a memory block for the MemoryPool"); 00079 if (!newBlock) 00080 { 00081 FatalError("Allocation failed when allocating memory for memory pool"); 00082 } 00083 00084 // Store a pointer to the allocated block 00085 blocks_[blocksCount_]=newBlock; 00086 blocksCount_++; 00087 00088 // If no entries array have been allocated yet, allocate it now 00089 if (!entries_) 00090 { 00091 entriesSize_=entriesPerBlock_; 00092 entries_=static_cast<TYPE**>(Malloc(sizeof(TYPE*)*entriesPerBlock_)); 00093 Assert(entries_,"Couldn't allocate a memory block for the MemoryPool"); 00094 if (!entries_) 00095 { 00096 FatalError("Allocation failed when allocating memory for memory pool"); 00097 } 00098 } 00099 00100 // If the entries array is full, double it and reallocate it 00101 if (entriesCount_+entriesPerBlock_>entriesSize_) 00102 { 00103 entriesSize_*=2; 00104 entries_=static_cast<TYPE**>(Realloc(entries_,sizeof(TYPE*)*entriesSize_)); 00105 Assert(entries_,"Couldn't allocate a memory block for the MemoryPool"); 00106 if (!entries_) 00107 { 00108 FatalError("Allocation failed when allocating memory for memory pool"); 00109 } 00110 } 00111 00112 00113 // Add all entries of the block to the list of unused entries 00114 for (int index = 0; index<entriesPerBlock_; index ++) 00115 { 00116 entries_[entriesCount_]=&newBlock[index]; 00117 entriesCount_++; 00118 } 00119 } 00120 00121 00122 //*** Allocate *** 00123 00124 template<class TYPE> 00125 TYPE* MemoryPool<TYPE>::Allocate() 00126 { 00127 // Check if there are any unused entries left 00128 if (entriesCount_== 0) 00129 { 00130 // If not, create a new block 00131 CreateBlock(); 00132 } 00133 00134 // Increase the number of currently used entries 00135 usedEntriesCount_++; 00136 00137 // Remove the last of the unused entries from the list of unused entries 00138 entriesCount_--; 00139 TYPE* memory=entries_[entriesCount_]; 00140 00141 // Create an object at the allocated memory position, and return it to the caller 00142 TYPE* object=new (memory) TYPE; 00143 return object; 00144 } 00145 00146 00147 //*** Free *** 00148 00149 template<class TYPE> 00150 void MemoryPool<TYPE>::Free(TYPE* object) 00151 { 00152 // Call the objects destructor 00153 object->~TYPE(); 00154 00155 // Decrease the number of currently used entries 00156 usedEntriesCount_--; 00157 00158 // If the entries array is full, double it and reallocate it 00159 if (entriesCount_>=entriesSize_) 00160 { 00161 entriesSize_*=2; 00162 entries_=static_cast<TYPE**>(Realloc(entries_,sizeof(TYPE*)*entriesSize_)); 00163 Assert(entries_,"Couldn't allocate a memory block for the MemoryPool"); 00164 if (!entries_) 00165 { 00166 FatalError("Allocation failed when allocating memory for memory pool"); 00167 } 00168 } 00169 00170 // Add entry to the list of unused entries 00171 entries_[entriesCount_]=object; 00172 entriesCount_++; 00173 } 00174 00175 00176 //*** IsInUse *** 00177 00178 template<class TYPE> 00179 bool MemoryPool<TYPE>::IsInUse() const 00180 { 00181 return (usedEntriesCount_>0); 00182 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
