![]()
|
pool.h00001 // 00002 // pool.h 00003 // 00004 // Copyright (C) 1996 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 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 //const int pool_data_alignment_bit = 14; 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 // Allocates a chunk of free memory, only initializing the size. 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 // This new can only be called with aligned memory. 00126 //void* operator new(size_t size, void* placement); 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 // void* operator new(size_t size, void* placement) { return placement; } 00284 00285 // Handle& allocate_handle(size_t size, int priority = 0); 00286 // void release(Handle&); 00287 00288 void* allocate(size_t size); 00289 void release(void*d); 00290 double* allocate_double(size_t n); 00291 void release(double*d); 00292 int* allocate_int(size_t n); 00293 void release(int*d); 00294 void print(std::ostream&o=ExEnv::out0()); 00295 void check(); 00296 }; 00297 00298 inline PoolData* 00299 Pool::voidptr_to_pd(void*d) 00300 { 00301 return (PoolData*)((char*)d - PoolData_aligned_size); 00302 } 00303 00304 inline double* 00305 Pool::allocate_double(size_t n) 00306 { 00307 return (double*) allocate(n*sizeof(double)); 00308 } 00309 00310 inline void 00311 Pool::release(double*d) 00312 { 00313 release((void*)d); 00314 } 00315 inline int* 00316 Pool::allocate_int(size_t n) 00317 { 00318 return (int*) allocate(n*sizeof(int)); 00319 } 00320 inline void 00321 Pool::release(int*d) 00322 { 00323 release((void*)d); 00324 } 00325 00326 } 00327 00328 #endif 00329 00330 00331 // Local Variables: 00332 // mode: c++ 00333 // c-file-style: "CLJ" 00334 // End: Generated at Fri Jan 10 08:14:09 2003 for MPQC 2.1.3 using the documentation package Doxygen 1.2.14. |