Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

glmemorypool.h

00001 /*
00002 Copyright (c) 2000-2003 Lee Thomason (www.grinninglizard.com)
00003 Grinning Lizard Utilities.
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any 
00010 purpose, including commercial applications, and to alter it and 
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must 
00014 not claim that you wrote the original software. If you use this 
00015 software in a product, an acknowledgment in the product documentation 
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and 
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source 
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef GRINLIZ_MEMORY_POOL
00027 #define GRINLIZ_MEMORY_POOL
00028 
00029 #include <string.h>
00030 #include "gldebug.h"
00031 
00032 namespace grinliz {
00033 
00034 /*      A memory pool that will dynamically grow as memory is needed.
00035 */
00036 class MemoryPool
00037 {
00038   public:
00039         MemoryPool( const char* _name, unsigned objectSize, unsigned blockSize = 4096 );
00040         ~MemoryPool();
00041 
00042         void* Alloc() {
00043                 void* ret = 0;
00044 
00045                 if ( !head ) {
00046                         NewBlock();
00047                         GLASSERT( head );
00048                 }
00049 
00050                 ret = head;
00051                 head = head->nextChunk;
00052 
00053                 #ifdef DEBUG
00054                         ++numChunks;
00055                         memset( ret, 0xaa, chunkSize );
00056                 #endif
00057 
00058                 return ret;
00059         }
00060 
00061         void Free( void* mem ) {
00062                 if ( !mem )
00063                         return;
00064 
00065                 Chunk* chunk = (Chunk*) mem;
00066 
00067                 #ifdef DEBUG
00068                         --numChunks;
00069                         memset( mem, 0xbb, chunkSize );
00070                 #endif
00071 
00072                 chunk->nextChunk = head;
00073                 head = chunk;
00074         }
00075 
00076         void FreePool();
00077 
00078         #ifdef DEBUG
00079         unsigned Blocks()       { return numBlocks; }
00080         unsigned Chunks()       { return numChunks; }
00081         unsigned MemoryUsed()   { return numBlocks * blockSize; }
00082         #endif
00083 
00084   private:
00085         struct Chunk
00086         {
00087                 Chunk* nextChunk;
00088         };
00089 
00090         struct Block
00091         {
00092                 Block* nextBlock;
00093                 Chunk* chunk;           // treated as an array of chunks.
00094         };
00095 
00096         void NewBlock();
00097 
00098         unsigned chunkSize;                     // size of chunk in bytes
00099         unsigned blockSize;                     // size of block in bytes
00100         unsigned chunksPerBlock;
00101         
00102         #ifdef DEBUG
00103         unsigned numBlocks;
00104         unsigned numChunks;
00105         #endif
00106         
00107         Block* rootBlock;
00108         Chunk* head;
00109 
00110         const char* name;
00111 };
00112 
00113 /*      A memory pool that has a fixed allocation.
00114         Essentially a cross between a linked list and an array.
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 /*      This is memory allocation for when you know exactly how much 
00178         memory is going to be needed. So it's a way to pre-allocate 
00179         while still using the new and delete operators.
00180 */
00181 
00182 class LinearMemoryPool
00183 {
00184   public:
00186         LinearMemoryPool( unsigned totalMemory );
00187 
00188         ~LinearMemoryPool();
00189 
00191         void* Alloc( unsigned allocate );
00192 
00195         void Free( void* mem )          {}
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

Generated on Sun Sep 25 16:25:49 2005 for Kyra by  doxygen 1.4.3