Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

Arena.H

Go to the documentation of this file.
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*/

Generated on Wed Apr 16 14:31:03 2003 for EBChombo by doxygen1.2.16