00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GUST_POOL_H
00021 #define GUST_POOL_H
00022
00023 #ifdef POOLDBG
00024 #include <iostream>
00025 #endif
00026
00027 namespace gust {
00028
00029 class PoolChunkList
00030 {
00031 public:
00032 void *head;
00033 void *chunks;
00034
00035 size_t elemsize;
00036 size_t growrate;
00037 };
00038
00039 const size_t PoolTabSize=2049;
00040 GULAPI
00041 extern PoolChunkList *PoolTab[2049];
00042 GULAPI
00043 extern PoolChunkList Pools[6];
00044
00045
00046 GULAPI
00047 void PoolGrow( PoolChunkList *pool );
00048 GULAPI
00049 void PoolFreeAll( void );
00050
00051
00052 #ifdef POOLDBG
00053 struct pooldbg
00054 {
00055 GULAPI static int freekey;
00056 GULAPI static int curmark;
00057 GULAPI static int count;
00058 GULAPI static pooldbg *head;
00059
00060 int key;
00061 int mark;
00062 size_t insize;
00063 size_t outsize;
00064 void *address;
00065
00066 pooldbg *next;
00067
00068 pooldbg( void *p, size_t sin, size_t sout )
00069 {
00070 count++;
00071
00072 address = p;
00073 insize = sin;
00074 outsize = sout;
00075
00076 key = ++freekey;
00077 mark = curmark;
00078
00079 next = head;
00080 head = this;
00081 }
00082 static void remove( void *p )
00083 {
00084 pooldbg *n = head;
00085 pooldbg *nprev = 0;
00086
00087 while( (n != 0) && (n->address != p) )
00088 {
00089 nprev = n;
00090 n = n->next;
00091 }
00092 if( n != 0 )
00093 {
00094 if( nprev == 0 ) head = n->next;
00095 else nprev->next = n->next;
00096 delete n;
00097 }
00098 else
00099 {
00100 std::cout << "ERROR: address not in list of reserved blocks\n";
00101 gul_halt();
00102 }
00103 }
00104 static void incmark()
00105 {
00106 curmark++;
00107 }
00108 ~pooldbg()
00109 {
00110 count--;
00111 }
00112 static void dump( int minmark )
00113 {
00114 pooldbg *n = head;
00115
00116 while( (n != 0) && (n->mark >= minmark) )
00117 {
00118 #ifndef _MSC_VER
00119 std::cout << n->address << ":(m = " << n->mark << ", i = " << n->insize
00120 << ", o = " << n->outsize << ")\n";
00121 #else
00122
00123 std::cout << n->address << ":(m = " << n->mark << ", i = "
00124 << (unsigned int)n->insize << ", o = "
00125 << (unsigned int)n->outsize << ")\n";
00126 #endif
00127 n = n->next;
00128 }
00129 }
00130 };
00131 #endif
00132
00133 inline void *PoolAlloc( const size_t insize, size_t *outsize )
00134 {
00135 PoolChunkList *pool;
00136 void *head;
00137
00138 if( !insize )
00139 {
00140 *outsize = 0;
00141 return 0;
00142 }
00143
00144 pool = PoolTab[insize];
00145
00146 head = pool->head;
00147
00148 if( head == NULL )
00149 {
00150 PoolGrow( pool );
00151 head = pool->head;
00152 }
00153
00154 pool->head = *((void **)head);
00155 *outsize = pool->elemsize;
00156 #ifdef POOLDBG
00157 new pooldbg( (void *)head, insize, *outsize );
00158 #endif
00159 return((void *)head);
00160 }
00161
00162 inline void PoolFree( void *ptr, const size_t size )
00163 {
00164 if( !ptr || !size ) return;
00165
00166 PoolChunkList *pool = PoolTab[size];
00167
00168 *((void **)ptr) = pool->head;
00169 pool->head = ptr;
00170 #ifdef POOLDBG
00171 pooldbg::remove( ptr );
00172 #endif
00173 }
00174
00175 inline void *PreferPoolAlloc( const size_t insize, size_t *outsize )
00176 {
00177 PoolChunkList *pool;
00178 void *head;
00179
00180 if( !insize )
00181 {
00182 *outsize = 0;
00183 return 0;
00184 }
00185
00186 if( insize >= PoolTabSize )
00187 {
00188 *outsize = insize;
00189
00190 void *p = malloc(insize);
00191 #ifdef POOLDBG
00192 new pooldbg( p, insize, *outsize );
00193 #endif
00194 return p;
00195 }
00196
00197 pool = PoolTab[insize];
00198
00199 head = pool->head;
00200
00201 if( head == NULL )
00202 {
00203 PoolGrow( pool );
00204 head = pool->head;
00205 }
00206
00207 pool->head = *((void **)head);
00208 *outsize = pool->elemsize;
00209 #ifdef POOLDBG
00210 new pooldbg( (void *)head, insize, *outsize );
00211 #endif
00212 return((void *)head);
00213 }
00214
00215 inline void PreferPoolFree( void *ptr, const size_t size )
00216 {
00217 if( !ptr || !size ) return;
00218
00219 if( size >= PoolTabSize )
00220 {
00221 free(ptr);
00222 #ifdef POOLDBG
00223 pooldbg::remove( ptr );
00224 #endif
00225 return;
00226 }
00227
00228 PoolChunkList *pool = PoolTab[size];
00229
00230 *((void **)ptr) = pool->head;
00231 pool->head = ptr;
00232 #ifdef POOLDBG
00233 pooldbg::remove( ptr );
00234 #endif
00235 }
00236
00237 }
00238
00239 #endif