00001 /* _______ __ 00002 / ___/ / ___ __ _ / / ___ 00003 / /__/ _ \/ _ \/ ' \/ _ \/ _ \ 00004 \___/_//_/\___/_/_/_/_.__/\___/ 00005 */ 00006 // 00007 // This software is copyright (C) by the Lawrence Berkeley 00008 // National Laboratory. Permission is granted to reproduce 00009 // this software for non-commercial purposes provided that 00010 // this notice is left intact. 00011 // 00012 // It is acknowledged that the U.S. Government has rights to 00013 // this software under Contract DE-AC03-765F00098 between 00014 // the U.S. Department of Energy and the University of 00015 // California. 00016 // 00017 // This software is provided as a professional and academic 00018 // contribution for joint exchange. Thus it is experimental, 00019 // is provided ``as is'', with no warranties of any kind 00020 // whatsoever, no support, no promise of updates, or printed 00021 // documentation. By using this software, you acknowledge 00022 // that the Lawrence Berkeley National Laboratory and 00023 // Regents of the University of California shall have no 00024 // liability with respect to the infringement of other 00025 // copyrights by any part of this software. 00026 // 00027 00028 #ifndef CH_ARENA 00029 #define CH_ARENA 00030 00031 // 00032 // $Id: Arena.H,v 1.6 2002/03/29 00:03:38 noel Exp $ 00033 // 00034 00035 #include <cstddef> 00036 #include <list> 00037 00038 // 00039 //@Man: 00040 //@Memo: A Virtual Base Class for Dynamic Memory Management 00041 /*@Doc: 00042 00043 This is a virtual base class for objects that manage their own dynamic 00044 memory allocation. Since it is a virtual base class, you have to derive 00045 something from it to use it. 00046 */ 00047 00048 class Arena; 00049 typedef std::list<Arena*> ArenaList; 00050 00051 class Arena 00052 { 00053 public: 00055 00057 Arena(); 00058 00060 00062 virtual ~Arena(); 00063 00064 /*@ManDoc: Allocate a dynamic memory arena of size sz. 00065 A pointer to this memory should be returned. 00066 */ 00067 virtual void* alloc (size_t sz) = 0; 00068 00069 /*@ManDoc: A pure virtual function for deleting the arena pointed 00070 to by pt. 00071 */ 00072 virtual void free (void* pt) = 0; 00073 00074 /*@ManDoc: Given a minimum required arena size of sz bytes, this returns 00075 the next largest arena size that will hold an integral number 00076 of objects of the largest of the types void*, long, 00077 double and function pointer. 00078 */ 00079 static size_t align (size_t sz); 00080 typedef void (*FP) (); 00081 00082 #ifdef ENABLE_MEMORY_TRACKING 00083 // data members used by memory tracking system. 00084 long int bytes; 00085 long int peak; 00086 static ArenaList* arenaList_; 00087 char name_[120]; 00088 #endif 00089 protected: 00090 // 00091 // Types used by align(). 00092 // 00093 00094 00095 union Word 00096 { 00097 void* p; 00098 double d; 00099 long l; 00100 FP f; 00101 }; 00102 }; 00103 00104 // 00105 // Inlines. 00106 // 00107 00108 inline 00109 size_t 00110 Arena::align (size_t s) 00111 { 00112 size_t x = s + sizeof(Word) - 1; 00113 x -= x%sizeof(Word); 00114 return x; 00115 } 00116 00117 // 00118 //@Man: 00119 //@Memo: A Concrete Class for Dynamic Memory Management 00120 /*@Doc: 00121 00122 This is the simplest dynamic memory management class derived from Arena. 00123 00124 Makes calls to ::operator new() and ::operator delete(). 00125 */ 00126 00127 class BArena 00128 : 00129 public Arena 00130 { 00131 public: 00132 00133 BArena(const char* name = "unnamed"); 00134 /*@ManDoc: Allocates a dynamic memory arena of size sz. Returns a 00135 pointer to this memory. 00136 */ 00137 virtual void* alloc (size_t sz); 00138 // 00139 //@ManDoc: Deletes the arena pointed to by pt. 00140 // 00141 virtual void free (void* pt); 00142 }; 00143 00144 #include <cstddef> 00145 00146 #include <set> 00147 #include <vector> 00148 using std::set; 00149 00150 00151 // 00152 //@Man: 00153 //@Memo: A Concrete Class for Dynamic Memory Management 00154 /*@Doc: 00155 00156 This is a coalescing memory manager. It allocates (possibly) large 00157 chunks of heap space and apportions it out as requested. It merges 00158 together neighboring chunks on each free(). 00159 */ 00160 00161 class CArena 00162 : 00163 public Arena 00164 { 00165 public: 00166 00167 /*@ManDoc: Construct a coalescing memory manager. `hunk\_size' is the 00168 minimum size of hunks of memory to allocate from the heap. 00169 If hunk\_size == 0 we use DefaultHunkSize as specified below. 00170 */ 00171 CArena (size_t hunk_size = 0); 00172 // 00173 //@ManDoc: The destructor. 00174 // 00175 virtual ~CArena (); 00176 // 00177 //@ManDoc: Allocate some memory. 00178 // 00179 virtual void* alloc (size_t nbytes); 00180 00181 /*@ManDoc: Free up allocated memory. Merge neighboring free memory chunks 00182 into largest possible chunk. 00183 */ 00184 virtual void free (void* ap); 00185 00186 /*@ManDoc: Mirror the C calloc() function. Returns zero'd memory of 00187 size nmemb*size. This is here so that we can implement 00188 malloc(3) and family. User's shouldn't use this function. 00189 */ 00190 void* calloc (size_t nmemb, size_t size); 00191 00192 /*@ManDoc: Mirror the C realloc() function. This is here so that we can 00193 implement malloc(3) and family. User's shouldn't use this 00194 function. 00195 */ 00196 void* realloc (void* ptr, size_t size); 00197 // 00198 //@ManDoc: The default memory hunk size to grab from the heap. 00199 // 00200 enum { DefaultHunkSize = 1024*1024 }; 00201 00202 protected: 00203 // 00204 // The nodes in our free list and block list. 00205 // 00206 class Node 00207 { 00208 public: 00209 // 00210 // The default constructor. 00211 // 00212 Node () 00213 : 00214 m_block(0), m_size(0) {} 00215 // 00216 // Another constructor. 00217 // 00218 Node (void* block, size_t size) 00219 : 00220 m_block(block), m_size(size) {} 00221 // 00222 // The copy constructor. 00223 // 00224 Node (const Node& rhs) 00225 : 00226 m_block(rhs.m_block), m_size(rhs.m_size) {} 00227 // 00228 // The copy assignment constructor. 00229 // 00230 Node& operator= (const Node& rhs) 00231 { 00232 m_block = rhs.m_block; 00233 m_size = rhs.m_size; 00234 return *this; 00235 } 00236 // 00237 // The "less-than" operator. 00238 // 00239 bool operator< (const Node& rhs) const 00240 { 00241 return m_block < rhs.m_block; 00242 } 00243 // 00244 // The equality operator. 00245 // 00246 bool operator== (const Node& rhs) const 00247 { 00248 return m_block == rhs.m_block; 00249 } 00250 // 00251 // The block address. 00252 // 00253 void* block () const { return m_block; } 00254 // 00255 // Set block address. 00256 // 00257 void block (void* blk) { m_block = blk; } 00258 // 00259 // The size of the memory block. 00260 // 00261 size_t size () const { return m_size; } 00262 // 00263 // Set size. 00264 // 00265 void size (size_t sz) { m_size = sz; } 00266 00267 private: 00268 // 00269 // The block of memory we reference. 00270 // 00271 void* m_block; 00272 // 00273 // The size of the block we represent. 00274 // 00275 size_t m_size; 00276 }; 00277 // 00278 // The type of our freelist and blocklist. 00279 // We use a set sorted from lo to hi memory addresses. 00280 // 00281 typedef set < Node > NL; 00282 // 00283 // The list of blocks allocated via ::operator new(). 00284 // 00285 std::vector<void*> m_alloc; 00286 // 00287 // The free list of allocated but not currently used blocks. 00288 // Maintained in lo to hi memory sorted order. 00289 // 00290 NL m_freelist; 00291 // 00292 // The list of busy blocks. 00293 // A block is either on the freelist or on the blocklist, but not on both. 00294 // 00295 NL m_busylist; 00296 // 00297 // The minimal size of hunks to request via ::operator new(). 00298 // 00299 size_t m_hunk; 00300 00301 private: 00302 // 00303 // Disallowed. 00304 // 00305 CArena (const CArena& rhs); 00306 CArena& operator= (const CArena& rhs); 00307 }; 00308 00309 // 00310 // The Arena used by BaseFab code. 00311 // 00312 extern Arena* The_FAB_Arena; 00313 00314 00315 #endif /*CH_ARENA*/