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: