MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
mem_alloc.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_MEM_ALLOC
13 #define MFEM_MEM_ALLOC
14 
15 #include "../config/config.hpp"
16 #include "array.hpp" // mfem::Swap
17 
18 namespace mfem
19 {
20 
21 template <class Elem, int Num>
22 class StackPart
23 {
24 public:
26  Elem Elements[Num];
27 };
28 
29 template <class Elem, int Num>
30 class Stack
31 {
32 private:
33  StackPart <Elem, Num> *TopPart, *TopFreePart;
34  int UsedInTop, SSize;
35 public:
36  /// Construct an empty stack.
37  Stack() { TopPart = TopFreePart = NULL; UsedInTop = Num; SSize = 0; }
38  /// Return the number of elements on the stack.
39  int Size() const { return SSize; }
40  /// Push element 'E' on the stack.
41  void Push (Elem E);
42  /// Pop an element off the stack and return it.
43  Elem Pop();
44  /// Clear the elements off the stack.
45  void Clear();
46 
47  /// Swap the data in this stack with the data in @a other.
48  void Swap(Stack<Elem, Num> &other);
49 
50  /// Return the number of bytes used by the stack.
51  size_t MemoryUsage() const;
52  ~Stack() { Clear(); }
53 };
54 
55 template <class Elem, int Num>
57 {
59  if (UsedInTop == Num)
60  {
61  if (TopFreePart == NULL)
62  {
63  aux = new StackPart <Elem, Num>;
64  }
65  else
66  {
67  TopFreePart = (aux = TopFreePart)->Prev;
68  }
69  aux->Prev = TopPart;
70  TopPart = aux;
71  UsedInTop = 0;
72  }
73  TopPart->Elements[UsedInTop++] = E;
74  SSize++;
75 }
76 
77 template <class Elem, int Num>
79 {
81  if (UsedInTop == 0)
82  {
83  TopPart = (aux = TopPart)->Prev;
84  aux->Prev = TopFreePart;
85  TopFreePart = aux;
86  UsedInTop = Num;
87  }
88  SSize--;
89  return TopPart->Elements[--UsedInTop];
90 }
91 
92 template <class Elem, int Num>
94 {
96  while (TopPart != NULL)
97  {
98  TopPart = (aux = TopPart)->Prev;
99  delete aux;
100  }
101  while (TopFreePart != NULL)
102  {
103  TopFreePart = (aux = TopFreePart)->Prev;
104  delete aux;
105  }
106  UsedInTop = Num;
107  SSize = 0;
108 }
109 
110 template <class Elem, int Num>
112 {
113  mfem::Swap(TopPart, other.TopPart);
114  mfem::Swap(TopFreePart, other.TopFreePart);
115  mfem::Swap(UsedInTop, other.UsedInTop);
116  mfem::Swap(SSize, other.SSize);
117 }
118 
119 template <class Elem, int Num>
121 {
122  size_t used_mem = 0;
123  StackPart <Elem, Num> *aux = TopPart;
124  while (aux != NULL)
125  {
126  used_mem += sizeof(StackPart <Elem, Num>);
127  aux = aux->Prev;
128  }
129  aux = TopFreePart;
130  while (aux != NULL)
131  {
132  used_mem += sizeof(StackPart <Elem, Num>);
133  aux = aux->Prev;
134  }
135  // Not counting sizeof(Stack <Elem, Num>)
136  return used_mem;
137 }
138 
139 
140 template <class Elem, int Num>
142 {
143 public:
145  Elem Elements[Num];
146 };
147 
148 template <class Elem, int Num>
149 class MemAlloc
150 {
151 private:
153  int AllocatedInLast;
154  Stack <Elem *, Num> UsedMem;
155 public:
156  MemAlloc() { Last = NULL; AllocatedInLast = Num; }
157  Elem *Alloc();
158  void Free (Elem *);
159  void Clear();
160  void Swap(MemAlloc<Elem, Num> &other);
161  size_t MemoryUsage() const;
162  ~MemAlloc() { Clear(); }
163 };
164 
165 template <class Elem, int Num>
167 {
169  if (UsedMem.Size() > 0)
170  {
171  return UsedMem.Pop();
172  }
173  if (AllocatedInLast == Num)
174  {
175  aux = Last;
176  Last = new MemAllocNode <Elem, Num>;
177  Last->Prev = aux;
178  AllocatedInLast = 0;
179  }
180  return &(Last->Elements[AllocatedInLast++]);
181 }
182 
183 template <class Elem, int Num>
185 {
186  UsedMem.Push (E);
187 }
188 
189 template <class Elem, int Num>
191 {
193  while (Last != NULL)
194  {
195  aux = Last->Prev;
196  delete Last;
197  Last = aux;
198  }
199  AllocatedInLast = Num;
200  UsedMem.Clear();
201 }
202 
203 template <class Elem, int Num>
205 {
206  mfem::Swap(Last, other.Last);
207  mfem::Swap(AllocatedInLast, other.AllocatedInLast);
208  UsedMem.Swap(other.UsedMem);
209 }
210 
211 template <class Elem, int Num>
213 {
214  size_t used_mem = UsedMem.MemoryUsage();
215  MemAllocNode <Elem, Num> *aux = Last;
216  while (aux != NULL)
217  {
218  used_mem += sizeof(MemAllocNode <Elem, Num>);
219  aux = aux->Prev;
220  }
221  // Not counting sizeof(MemAlloc <Elem, Num>)
222  return used_mem;
223 }
224 
225 }
226 
227 #endif
Elem * Alloc()
Definition: mem_alloc.hpp:166
Elem Elements[Num]
Definition: mem_alloc.hpp:26
void Free(Elem *)
Definition: mem_alloc.hpp:184
size_t MemoryUsage() const
Definition: mem_alloc.hpp:212
Elem Elements[Num]
Definition: mem_alloc.hpp:145
void Swap(Stack< Elem, Num > &other)
Swap the data in this stack with the data in other.
Definition: mem_alloc.hpp:111
Stack()
Construct an empty stack.
Definition: mem_alloc.hpp:37
size_t MemoryUsage() const
Return the number of bytes used by the stack.
Definition: mem_alloc.hpp:120
StackPart< Elem, Num > * Prev
Definition: mem_alloc.hpp:25
int Size() const
Return the number of elements on the stack.
Definition: mem_alloc.hpp:39
void Push(Elem E)
Push element &#39;E&#39; on the stack.
Definition: mem_alloc.hpp:56
Elem Pop()
Pop an element off the stack and return it.
Definition: mem_alloc.hpp:78
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:630
void Swap(MemAlloc< Elem, Num > &other)
Definition: mem_alloc.hpp:204
void Clear()
Clear the elements off the stack.
Definition: mem_alloc.hpp:93
MemAllocNode< Elem, Num > * Prev
Definition: mem_alloc.hpp:144