Chombo + EB  3.0
Arena.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _ARENA_H_
12 #define _ARENA_H_
13 
14 #include <cstddef>
15 
16 #ifdef CH_USE_MEMORY_TRACKING
17 #include <list>
18 #include <cstddef>
19 #endif
20 
21 #include <set>
22 #include <vector>
23 #include "BaseNamespaceHeader.H"
24 
25 #ifdef CH_USE_MEMORY_TRACKING
26 class Arena;
27 typedef std::list<Arena*> ArenaList;
28 #endif
29 
30 using std::set;
31 
32 /// A Virtual Base Class for Dynamic Memory Managemen
33 /**
34 A Virtual Base Class for Dynamic Memory Management
35 
36  This is a virtual base class for objects that manage their own dynamic
37  memory allocation. Since it is a virtual base class, you have to derive
38  something from it to use it.
39 */
40 class Arena
41 {
42 public:
43  /// base class constructor
44  /** base class constructor. registers Arena object with
45  memory tracking system
46  */
47  Arena();
48 
49  /// base class destructor.
50  /** base class destructor. unregisters Arena object with
51  memory tracking system
52  */
53  virtual ~Arena();
54 
55  /**
56  Allocate a dynamic memory arena of size a_sz.
57  A pointer to this memory should be returned.
58  */
59  virtual void* alloc(size_t a_sz) = 0;
60 
61  /**
62  A pure virtual function for deleting the arena pointed to by a_pt.
63  */
64  virtual void free(void* a_pt) = 0;
65 
66  /**
67  Given a minimum required arena size of a_sz bytes, this returns
68  the next largest arena size that will hold an integral number
69  of objects of the largest of the types void*, long,
70  double and function pointer.
71  */
72  static size_t align(size_t a_sz);
73 
74  typedef void (*FP)();
75 
76 #ifdef CH_USE_MEMORY_TRACKING
77  /**data members used by memory tracking system.*/
78 
79  /*@{*/
80  long int bytes;
81  long int peak;
82  static ArenaList* arenaList_;
83  static int NSIZE;
84  char name_[120];
85  /*@}*/
86 #endif
87 
88 
89 protected:
90  //
91  // Types used by align().
92  //
93 #ifndef DOXYGEN
94 
95  union Word
96  {
97  void* p;
98  double d;
99  long l;
100  FP f;
101  };
102 #endif
103 };
104 
105 //
106 // Inlines.
107 //
108 
109 inline size_t Arena::align (size_t a_s)
110 {
111  size_t x = a_s + sizeof(Word) - 1;
112  x -= x % sizeof(Word);
113  return x;
114 }
115 
116 /// A Concrete Class for Dynamic Memory Management
117 /**
118 
119  This is the simplest dynamic memory management class derived from Arena.
120 
121  Makes calls to ::operator new() and ::operator delete().
122 */
123 
124 class BArena: public Arena
125 {
126 public:
127  ///
128  /**
129  optional @param a_name used by memory tracker to distinguish
130  between different memory Arenas
131  */
132  BArena(const char* a_name = "unnamed");
133 
134  BArena(const std::string& a_name);
135 
136 
137  /**: Allocates a dynamic memory arena of size a_sz. Returns a
138  pointer to this memory.
139  */
140  virtual void* alloc (size_t a_sz);
141 
142  /// Deletes the arena pointed to by a_pt.
143  virtual void free (void* a_pt);
144 };
145 
146 /// A Concrete Class for Dynamic Memory Management
147 /**
148 
149  This is a coalescing memory manager. It allocates (possibly) large
150  chunks of heap space and apportions it out as requested. It merges
151  together neighboring chunks on each free().
152 */
153 
154 class CArena: public Arena
155 {
156 public:
157  /**: Construct a coalescing memory manager. `a_hunk_size' is the
158  minimum size of hunks of memory to allocate from the heap.
159  If a_hunk_size == 0 we use DefaultHunkSize as specified below.
160  */
161  CArena(size_t a_hunk_size = 0);
162 
163  /// The destructor.
164  virtual ~CArena();
165 
166  /// Allocate some memory.
167  virtual void* alloc(size_t a_nbytes);
168 
169  /** Free up allocated memory. Merge neighboring free memory chunks
170  into largest possible chunk.
171  */
172  virtual void free(void* a_vp);
173 
174 #if 0
175  /** Mirror the C calloc() function. Returns zero'd memory of
176  size a_nmemb*a_size. This is here so that we can implement
177  malloc(3) and family. Users shouldn't use this function.
178  */
179  void* calloc(size_t a_nmemb,
180  size_t a_size);
181 
182  /** Mirror the C realloc() function. This is here so that we can
183  implement malloc(3) and family. Users shouldn't use this
184  function.
185  */
186  void* realloc (void* a_ptr,
187  size_t a_size);
188 #endif
189 
190  /// The default memory hunk size to grab from the heap.
191  enum
192  {
193  DefaultHunkSize = 1024*1024
194  };
195 
196 
197 protected:
198  //
199  // The nodes in our free list and block list.
200  //
201 #ifndef DOXYGEN
202  class Node
203  {
204  public:
205  //
206  // The default constructor.
207  //
208  Node()
209  :
210  m_block(0),
211  m_size(0)
212  {}
213  //
214  // Another constructor.
215  //
216  Node(void* a_block, size_t a_size)
217  :
218  m_block(a_block),
219  m_size(a_size)
220  {}
221  //
222  // The copy constructor.
223  //
224  Node(const Node& a_rhs)
225  :
226  m_block(a_rhs.m_block),
227  m_size(a_rhs.m_size)
228  {}
229  //
230  // The copy assignment constructor.
231  //
232  Node& operator = (const Node& a_rhs)
233  {
234  m_block = a_rhs.m_block;
235  m_size = a_rhs.m_size;
236  return *this;
237  }
238  //
239  // The "less-than" operator.
240  //
241  bool operator < (const Node& a_rhs) const
242  {
243  return m_block < a_rhs.m_block;
244  }
245  //
246  // The equality operator.
247  //
248  bool operator == (const Node& a_rhs) const
249  {
250  return m_block == a_rhs.m_block;
251  }
252  //
253  // The block address.
254  //
255  void* block() const
256  {
257  return m_block;
258  }
259  //
260  // Set block address.
261  //
262  void block (void* a_blk)
263  {
264  m_block = a_blk;
265  }
266  //
267  // The size of the memory block.
268  //
269  size_t size() const
270  {
271  return m_size;
272  }
273  //
274  // Set size.
275  //
276  void size(size_t a_sz)
277  {
278  m_size = a_sz;
279  }
280 
281 
282  private:
283  //
284  // The block of memory we reference.
285  //
286  void* m_block;
287  //
288  // The size of the block we represent.
289  //
290  size_t m_size;
291  };
292 
293  //
294  // The type of our freelist and blocklist.
295  // We use a set sorted from lo to hi memory addresses.
296  //
297  typedef set < Node > NL;
298 
299  //
300  // The list of blocks allocated via ::operator new().
301  //
302  std::vector<void*> m_alloc;
303 
304  //
305  // The free list of allocated but not currently used blocks.
306  // Maintained in lo to hi memory sorted order.
307  //
308  NL m_freelist;
309 
310  //
311  // The list of busy blocks.
312  // A block is either on the freelist or on the blocklist, but not on both.
313  //
314  NL m_busylist;
315 
316  //
317  // The minimal size of hunks to request via ::operator new().
318  //
319  size_t m_hunk;
320 #endif
321 
322 
323 private:
324  //
325  // Disallowed.
326  //
327  CArena (const CArena& a_rhs);
328  CArena& operator= (const CArena& a_rhs);
329 };
330 
331 //
332 // The Arena used by BaseFab code.
333 //
334 extern Arena* The_FAB_Arena;
335 
336 #include "BaseNamespaceFooter.H"
337 #endif /*CH_ARENA*/
static size_t align(size_t a_sz)
Definition: Arena.H:109
A Concrete Class for Dynamic Memory Management.
Definition: Arena.H:124
virtual void * alloc(size_t a_sz)=0
virtual void free(void *a_pt)=0
Arena()
base class constructor
A Virtual Base Class for Dynamic Memory Managemen.
Definition: Arena.H:40
bool operator<(const FaceIndex &f1, const FaceIndex &f2)
Definition: FaceIndex.H:204
virtual ~Arena()
base class destructor.
A Concrete Class for Dynamic Memory Management.
Definition: Arena.H:154
Arena * The_FAB_Arena
void(* FP)()
Definition: Arena.H:74