PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PMemPool.h 00004 // 00005 // Copyright (C) 2005 Nicolas Chapados 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: PMemPool.h 3994 2005-08-25 13:35:03Z chapados $ 00037 ******************************************************* */ 00038 00039 // Authors: Nicolas Chapados 00040 00044 #ifndef PMemPool_INC 00045 #define PMemPool_INC 00046 00047 // From C++ stdlib 00048 #include <new> 00049 #include <list> 00050 #include <map> 00051 00052 // From PLearn 00053 #include "PP.h" 00054 00055 namespace PLearn { 00056 00057 // Forward-declaration 00058 class PMemPool; 00059 00060 //##### PMemArena ########################################################### 00061 00075 class PMemArena : public PPointable 00076 { 00077 friend class PMemPool; 00078 00079 protected: 00080 void* storage; 00081 void* end_of_storage; 00082 size_t object_size; 00083 size_t allocated_objects; 00084 char* watermark; 00085 void* free_list; 00086 00088 union Aligner { 00089 char a; 00090 int b; 00091 long c; 00092 double d; 00093 void* x; 00094 }; 00095 00096 public: 00099 PMemArena(size_t object_size, size_t max_num_objects); 00100 00103 ~PMemArena(); 00104 00106 inline void* allocate(); 00107 00109 void deallocate(void* p); 00110 00113 bool belongsToArena(void* p) const 00114 { return p >= storage && p < end_of_storage; } 00115 00117 bool empty() const { return allocated_objects == 0; } 00118 00119 private: 00121 PMemArena(const PMemArena&); 00122 void operator=(const PMemArena&); 00123 }; 00124 00125 00126 //##### PMemPool ############################################################ 00127 00145 class PMemPool : public PPointable 00146 { 00147 protected: 00148 std::list< PP<PMemArena> > arenas; 00149 PMemArena* last_arena; 00150 size_t object_size; 00151 size_t initial_arena_size; 00152 size_t cur_arena_size; 00153 float arena_growth_factor; 00154 map<void*, PMemArena*> stormap; 00155 bool fast_deallocate; 00156 void* free_list; 00157 00158 public: 00162 PMemPool(size_t object_size, size_t initial_arena_size, 00163 float growth_factor = 1.5, 00164 bool use_fast_deallocator = true); 00165 00166 // Default destructor is OK 00167 00169 void* allocate(); 00170 00174 void deallocate(void* p); 00175 00177 bool empty() const { return arenas.size() == 0; } 00178 00180 void purge_memory(); 00181 00182 protected: 00185 void* allocateFromArenas(); 00186 00188 PMemArena* newArena(); 00189 }; 00190 00191 00192 //##### PObjectPool ######################################################### 00193 00200 template <class T> 00201 class PObjectPool : public PMemPool 00202 { 00203 typedef PMemPool inherited; 00204 00205 public: 00206 PObjectPool(size_t initial_arena_size, float growth_factor = 1.5, 00207 bool use_fast_deallocator = true) 00208 : inherited(sizeof(T), initial_arena_size, growth_factor, 00209 use_fast_deallocator) 00210 { } 00211 00213 T* allocate() { return static_cast<T*>(inherited::allocate()); } 00214 00217 void deallocate(T* p) { inherited::deallocate(p); } 00218 }; 00219 00220 00221 00222 //##### PSystemPool ######################################################### 00223 00228 //##### Some Implementations ################################################ 00229 00230 inline void* PMemArena::allocate() 00231 { 00232 // See if we can allocate from watermark 00233 if (watermark > storage) { 00234 watermark -= object_size; 00235 allocated_objects++; 00236 return watermark; 00237 } 00238 // Otherwise check if we can allocate from free list 00239 else if (free_list) { 00240 void** to_return = static_cast<void**>(free_list); 00241 free_list = *to_return; 00242 allocated_objects++; 00243 return to_return; 00244 } 00245 // Otherwise, cannot allocate at all: return NULL 00246 else 00247 return 0; 00248 } 00249 00250 } // end of namespace PLearn 00251 00252 00253 #endif 00254 00255 00256 /* 00257 Local Variables: 00258 mode:c++ 00259 c-basic-offset:4 00260 c-file-style:"stroustrup" 00261 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00262 indent-tabs-mode:nil 00263 fill-column:79 00264 End: 00265 */ 00266 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :