00001 /*
00002 Copyright (c) 2000-2003 Lee Thomason (www.grinninglizard.com)
00003
00004 Grinning Lizard Utilities. Note that software that uses the
00005 utility package (including Lilith3D and Kyra) have more restrictive
00006 licences which applies to code outside of the utility package.
00007
00008
00009 This software is provided 'as-is', without any express or implied
00010 warranty. In no event will the authors be held liable for any
00011 damages arising from the use of this software.
00012
00013 Permission is granted to anyone to use this software for any
00014 purpose, including commercial applications, and to alter it and
00015 redistribute it freely, subject to the following restrictions:
00016
00017 1. The origin of this software must not be misrepresented; you must
00018 not claim that you wrote the original software. If you use this
00019 software in a product, an acknowledgment in the product documentation
00020 would be appreciated but is not required.
00021
00022 2. Altered source versions must be plainly marked as such, and
00023 must not be misrepresented as being the original software.
00024
00025 3. This notice may not be removed or altered from any source
00026 distribution.
00027 */
00028
00029
00030
00031 #ifndef GL_MEMORY_POOL
00032 #define GL_MEMORY_POOL
00033
00034 #include "gldebug.h"
00035
00036 /* A memory pool that will dynamically grow as memory is needed.
00037 */
00038 class GlMemoryPool
00039 {
00040 public:
00041 GlMemoryPool( const char* _name, unsigned objectSize, unsigned blockSize = 4096 );
00042 ~GlMemoryPool();
00043
00044 void* Alloc();
00045 void Free( void* mem );
00046
00047 void FreePool();
00048
00049 private:
00050 struct Chunk
00051 {
00052 Chunk* nextChunk;
00053 };
00054
00055 struct Block
00056 {
00057 Block* nextBlock;
00058 Chunk* chunk; // treated as an array of chunks.
00059 };
00060
00061 void NewBlock();
00062
00063 unsigned chunkSize; // size of chunk in 32bit words
00064 unsigned blockSize; // size of block in words
00065 unsigned chunksPerBlock;
00066
00067 unsigned numBlocks;
00068 unsigned numChunks;
00069
00070 Block* rootBlock;
00071 Chunk* head;
00072
00073 const char* name;
00074 };
00075
00076 /* A memory pool that has a fixed allocation.
00077 Essentially a cross between a linked list and an array.
00078 */
00079 template < class T, int COUNT >
00080 class GlFixedMemoryPool
00081 {
00082 private:
00083 struct Chunk
00084 {
00085 Chunk* next;
00086 };
00087
00088 public:
00089 GlFixedMemoryPool()
00090 {
00091 GLASSERT( sizeof( T ) >= sizeof( Chunk* ) );
00092 for( int i=0; i<COUNT-1; ++i )
00093 {
00094 ( (Chunk*)(&memory[i]) )->next = (Chunk*)(&memory[i+1]);
00095 }
00096 ( (Chunk*)(&memory[COUNT-1]) )->next = 0;
00097 root = ( (Chunk*)(&memory[0]) );
00098 inUse = 0;
00099 }
00100
00101 ~GlFixedMemoryPool() {}
00102
00103 T* Alloc()
00104 {
00105 T* ret = 0;
00106 if ( root )
00107 {
00108 ret = (T*) root;
00109 root = root->next;
00110 ++inUse;
00111 }
00112 return ret;
00113 }
00114
00115 void Free( T* _mem )
00116 {
00117 if ( _mem )
00118 {
00119 Chunk* mem = (Chunk*) _mem;
00120 #ifdef DEBUG
00121 memset( mem, 0xfe, sizeof( T ) );
00122 #endif
00123 mem->next = root;
00124 root = mem;
00125 --inUse;
00126 }
00127 }
00128
00129 unsigned InUse() { return inUse; }
00130 unsigned Remain() { return COUNT - inUse; }
00131 bool Contains( T* mem ) { return mem >= memory && mem < &memory[COUNT]; }
00132
00133 private:
00134 T memory[ COUNT ];
00135 unsigned inUse;
00136 Chunk* root;
00137 };
00138
00139
00140 /* This is memory allocation for when you know exactly how much
00141 memory is going to be needed. So it's a way to pre-allocate
00142 while still using the new and delete operators.
00143 */
00144
00145 class GlLinearMemoryPool
00146 {
00147 public:
00149 GlLinearMemoryPool( unsigned totalMemory );
00150
00151 ~GlLinearMemoryPool();
00152
00154 void* Alloc( unsigned allocate );
00155
00158 void Free( void* mem ) {}
00159
00161 bool OutOfMemory() { return current == end; }
00162
00163 public:
00164 char* base;
00165 char* current;
00166 char* end;
00167 };
00168
00169 #endif
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001