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