Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

pool.h

00001 //
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 const int pool_data_alignment_bit = 3;
00044 //const int pool_data_alignment_bit = 14;
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     // Allocates a chunk of free memory, only initializing the size.
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     // This new can only be called with aligned memory.
00124     //void* operator new(size_t size, void* placement);
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 //     void* operator new(size_t size, void* placement) { return placement; }
00282 
00283 //     Handle& allocate_handle(size_t size, int priority = 0);
00284 //     void release(Handle&);
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 // Local Variables:
00328 // mode: c++
00329 // c-file-style: "CLJ"
00330 // End:

Generated at Thu Oct 4 18:08:46 2001 for MPQC 2.0.0 using the documentation package Doxygen 1.2.5.