Google

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 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.