00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef GRINLIZ_MEMORY_POOL
00027 #define GRINLIZ_MEMORY_POOL
00028
00029 #include "gldebug.h"
00030
00031 #ifdef DEBUG
00032 #include <string.h>
00033 #endif
00034
00035
00036 namespace grinliz {
00037
00038
00039
00040 class MemoryPool
00041 {
00042 public:
00043 MemoryPool( const char* _name, unsigned objectSize, unsigned blockSize = 4096 );
00044 ~MemoryPool();
00045
00046 void* Alloc() {
00047 void* ret = 0;
00048
00049 if ( !head ) {
00050 NewBlock();
00051 GLASSERT( head );
00052 }
00053
00054 ret = head;
00055 head = head->nextChunk;
00056
00057 ++numChunks;
00058 #ifdef DEBUG
00059 memset( ret, 0xaa, chunkSize );
00060 #endif
00061
00062 return ret;
00063 }
00064
00065 void Free( void* mem ) {
00066 if ( !mem )
00067 return;
00068
00069 Chunk* chunk = (Chunk*) mem;
00070
00071 --numChunks;
00072 #ifdef DEBUG
00073 memset( mem, 0xbb, chunkSize );
00074 #endif
00075
00076 chunk->nextChunk = head;
00077 head = chunk;
00078 }
00079
00080 void FreePool();
00081
00082 unsigned Blocks() { return numBlocks; }
00083 unsigned Chunks() { return numChunks; }
00084 unsigned MemoryUsed() { return numBlocks * blockSize; }
00085
00086 private:
00087 struct Chunk
00088 {
00089 Chunk* nextChunk;
00090 };
00091
00092 struct Block
00093 {
00094 Block* nextBlock;
00095 Chunk* chunk;
00096 };
00097
00098 void NewBlock();
00099
00100 unsigned chunkSize;
00101 unsigned blockSize;
00102 unsigned chunksPerBlock;
00103
00104 unsigned numBlocks;
00105 unsigned numChunks;
00106
00107 Block* rootBlock;
00108 Chunk* head;
00109
00110 const char* name;
00111 };
00112
00113
00114
00115
00116 template < class T, int COUNT >
00117 class FixedMemoryPool
00118 {
00119 private:
00120 struct Chunk
00121 {
00122 Chunk* next;
00123 };
00124
00125 public:
00126 FixedMemoryPool()
00127 {
00128 GLASSERT( sizeof( T ) >= sizeof( Chunk* ) );
00129 for( int i=0; i<COUNT-1; ++i )
00130 {
00131 ( (Chunk*)(&memory[i]) )->next = (Chunk*)(&memory[i+1]);
00132 }
00133 ( (Chunk*)(&memory[COUNT-1]) )->next = 0;
00134 root = ( (Chunk*)(&memory[0]) );
00135 inUse = 0;
00136 }
00137
00138 ~FixedMemoryPool() {}
00139
00140 T* Alloc()
00141 {
00142 T* ret = 0;
00143 if ( root )
00144 {
00145 ret = (T*) root;
00146 root = root->next;
00147 ++inUse;
00148 }
00149 return ret;
00150 }
00151
00152 void Free( T* _mem )
00153 {
00154 if ( _mem )
00155 {
00156 Chunk* mem = (Chunk*) _mem;
00157 #ifdef DEBUG
00158 memset( mem, 0xfe, sizeof( T ) );
00159 #endif
00160 mem->next = root;
00161 root = mem;
00162 --inUse;
00163 }
00164 }
00165
00166 unsigned InUse() { return inUse; }
00167 unsigned Remain() { return COUNT - inUse; }
00168 bool Contains( T* mem ) { return mem >= memory && mem < &memory[COUNT]; }
00169
00170 private:
00171 T memory[ COUNT ];
00172 unsigned inUse;
00173 Chunk* root;
00174 };
00175
00176
00177
00178
00179
00180
00181
00182
00183 class LinearMemoryPool
00184 {
00185 public:
00187 LinearMemoryPool( unsigned totalMemory );
00188 ~LinearMemoryPool();
00189
00191 void* Alloc( unsigned allocate );
00192
00195 void Free( void* ) {}
00196
00198 bool OutOfMemory() { return current == end; }
00199
00200 public:
00201 char* base;
00202 char* current;
00203 char* end;
00204 };
00205
00206 };
00207
00208 #endif