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
00027
00028 #ifdef __GNUC__
00029 #pragma interface
00030 #endif
00031
00032 #ifndef _util_group_pool_h
00033 #define _util_group_pool_h
00034
00035 #include <stdlib.h>
00036 #include <new>
00037 #include <iostream>
00038
00039 #include <util/misc/exenv.h>
00040
00041 #undef DEBUG_POOL
00042
00043 const int pool_data_alignment_bit = 3;
00044
00045 const size_t pool_data_alignment = 1<<pool_data_alignment_bit;
00046 inline size_t
00047 align_pool_data(size_t size)
00048 {
00049 return (size + pool_data_alignment - 1)
00050 & (~ (pool_data_alignment - 1));
00051 }
00052 inline void*
00053 align_pool_data(void* ptr)
00054 {
00055 return (void*)( (unsigned long) ((char*)ptr + pool_data_alignment - 1)
00056 & (~ (pool_data_alignment - 1)));
00057 }
00058 inline size_t
00059 align_pool_data_downward(size_t size)
00060 {
00061 return size & (~ (pool_data_alignment - 1));
00062 }
00063 inline void*
00064 align_pool_data_downward(void* ptr)
00065 {
00066 return (void*) ( (unsigned long) ptr & (~ (pool_data_alignment - 1)));
00067 }
00068
00069
00070
00071 class PoolData;
00072 struct FreeData {
00073 PoolData* next_free_;
00074 PoolData* prev_free_;
00075 };
00076
00077
00078
00079 struct UsedData {
00080 unsigned int flags;
00081 unsigned int held_:16;
00082 int priority_:15;
00083 unsigned int fixed_:1;
00084 };
00085
00086
00087
00088 class PoolData {
00089 public:
00090 enum {magic = 0x1f1d1e1c};
00091 int magic_;
00092 size_t size_;
00093 unsigned int free_:1;
00094 unsigned int flags_:15;
00095 private:
00096 PoolData* next_;
00097 PoolData* prev_;
00098 public:
00099 union {
00100 FreeData f;
00101 UsedData u;
00102 };
00103
00104
00105 PoolData(size_t size);
00106
00107 PoolData* next();
00108 PoolData* prev();
00109
00110 void next(PoolData*);
00111 void prev(PoolData*);
00112 void prev_next(PoolData*,PoolData*);
00113
00114 PoolData* next_free();
00115 PoolData* prev_free();
00116
00117 void next_free(PoolData*);
00118 void prev_free(PoolData*);
00119 void prev_next_free(PoolData*,PoolData*);
00120
00121 void set_magic(int = magic);
00122
00123
00124
00125 void* data();
00126
00127 void check(void*lower=(void*)0x0,void*upper=(void*)0x7fffffffL);
00128 };
00129
00130 const int PoolData_aligned_size = (sizeof(PoolData) + pool_data_alignment - 1)
00131 & (~ (pool_data_alignment - 1));
00132 inline void* PoolData::data()
00133 {
00134 return (void*)(((char*)this) + PoolData_aligned_size);
00135 }
00136
00137 inline PoolData*
00138 PoolData::next()
00139 {
00140 return next_;
00141 }
00142
00143 inline PoolData*
00144 PoolData::prev()
00145 {
00146 return prev_;
00147 }
00148
00149 inline void
00150 PoolData::next(PoolData*p)
00151 {
00152 next_ = p;
00153 #ifdef DEBUG_POOL
00154 if (next_ && prev_ && (next_ < prev_)) {
00155 ExEnv::err() << "PoolData::next(PoolData*): next < prev" << endl;
00156 abort();
00157 }
00158 #endif
00159 }
00160
00161 inline void
00162 PoolData::prev(PoolData*p)
00163 {
00164 prev_ = p;
00165 #ifdef DEBUG_POOL
00166 if (next_ && prev_ && (next_ < prev_)) {
00167 ExEnv::err() << "PoolData::prev(PoolData*): next < prev" << endl;
00168 abort();
00169 }
00170 #endif
00171 }
00172
00173 inline void
00174 PoolData::prev_next(PoolData*p,PoolData*n)
00175 {
00176 prev_ = p;
00177 next_ = n;
00178 #ifdef DEBUG_POOL
00179 if (next_ && prev_ && (next_ < prev_)) {
00180 ExEnv::err() << "PoolData::prev_next: next < prev" << endl;
00181 abort();
00182 }
00183 #endif
00184 }
00185
00186
00187
00188 inline PoolData*
00189 PoolData::next_free()
00190 {
00191 #ifdef DEBUG_POOL
00192 if (!free_) {
00193 ExEnv::err() << "PoolData::next_free(): datum is not free" << endl;
00194 abort();
00195 }
00196 #endif
00197 return f.next_free_;
00198 }
00199
00200 inline PoolData*
00201 PoolData::prev_free()
00202 {
00203 #ifdef DEBUG_POOL
00204 if (!free_) {
00205 ExEnv::err() << "PoolData::prev_free(): datum is not free" << endl;
00206 abort();
00207 }
00208 #endif
00209 return f.prev_free_;
00210 }
00211
00212 inline void
00213 PoolData::next_free(PoolData*p)
00214 {
00215 #ifdef DEBUG_POOL
00216 if (!free_) {
00217 ExEnv::err() << "PoolData::next_free(PoolData*): datum is not free" << endl;
00218 abort();
00219 }
00220 #endif
00221 f.next_free_ = p;
00222 }
00223
00224 inline void
00225 PoolData::prev_free(PoolData*p)
00226 {
00227 #ifdef DEBUG_POOL
00228 if (!free_) {
00229 ExEnv::err() << "PoolData::prev_free(PoolData*): datum is not free" << endl;
00230 abort();
00231 }
00232 #endif
00233 f.prev_free_ = p;
00234 }
00235
00236 inline void
00237 PoolData::prev_next_free(PoolData*p,PoolData*n)
00238 {
00239 #ifdef DEBUG_POOL
00240 if (!free_) {
00241 ExEnv::err() << "PoolData::prev_next_free: datum is not free" << endl;
00242 abort();
00243 }
00244 #endif
00245 f.prev_free_ = p;
00246 f.next_free_ = n;
00247 }
00248
00249 inline
00250 PoolData::PoolData(size_t size):
00251 magic_(magic),
00252 size_(size-PoolData_aligned_size)
00253 {
00254 }
00255
00256 inline void
00257 PoolData::set_magic(int magic_a)
00258 {
00259 magic_ = magic_a;
00260 }
00261
00262
00263
00264 class Pool {
00265 protected:
00266 enum { freelist_size = sizeof(size_t)*8 };
00267 PoolData* freelist_[freelist_size];
00268
00269 size_t size_;
00270
00271 PoolData* firstdatum_;
00272 PoolData* voidptr_to_pd(void*d);
00273
00274 int freelist_find_slot(size_t);
00275 void freelist_add(PoolData*);
00276 void freelist_del(PoolData*);
00277 public:
00278 Pool(size_t);
00279 ~Pool();
00280
00281
00282
00283
00284
00285
00286 void* allocate(size_t size);
00287 void release(void*d);
00288 double* allocate_double(size_t n);
00289 void release(double*d);
00290 int* allocate_int(size_t n);
00291 void release(int*d);
00292 void print(std::ostream&o=ExEnv::out());
00293 void check();
00294 };
00295
00296 inline PoolData*
00297 Pool::voidptr_to_pd(void*d)
00298 {
00299 return (PoolData*)((char*)d - PoolData_aligned_size);
00300 }
00301
00302 inline double*
00303 Pool::allocate_double(size_t n)
00304 {
00305 return (double*) allocate(n*sizeof(double));
00306 }
00307
00308 inline void
00309 Pool::release(double*d)
00310 {
00311 release((void*)d);
00312 }
00313 inline int*
00314 Pool::allocate_int(size_t n)
00315 {
00316 return (int*) allocate(n*sizeof(int));
00317 }
00318 inline void
00319 Pool::release(int*d)
00320 {
00321 release((void*)d);
00322 }
00323
00324 #endif
00325
00326
00327
00328
00329
00330