MFEM  v4.1.0
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-2020, 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  Stack() { TopPart = TopFreePart = NULL; UsedInTop = Num; SSize = 0; }
37  int Size() const { return SSize; }
38  void Push (Elem E);
39  Elem Pop();
40  void Clear();
41  void Swap(Stack<Elem, Num> &other);
42  size_t MemoryUsage() const;
43  ~Stack() { Clear(); }
44 };
45 
46 template <class Elem, int Num>
48 {
50  if (UsedInTop == Num)
51  {
52  if (TopFreePart == NULL)
53  {
54  aux = new StackPart <Elem, Num>;
55  }
56  else
57  {
58  TopFreePart = (aux = TopFreePart)->Prev;
59  }
60  aux->Prev = TopPart;
61  TopPart = aux;
62  UsedInTop = 0;
63  }
64  TopPart->Elements[UsedInTop++] = E;
65  SSize++;
66 }
67 
68 template <class Elem, int Num>
70 {
72  if (UsedInTop == 0)
73  {
74  TopPart = (aux = TopPart)->Prev;
75  aux->Prev = TopFreePart;
76  TopFreePart = aux;
77  UsedInTop = Num;
78  }
79  SSize--;
80  return TopPart->Elements[--UsedInTop];
81 }
82 
83 template <class Elem, int Num>
85 {
87  while (TopPart != NULL)
88  {
89  TopPart = (aux = TopPart)->Prev;
90  delete aux;
91  }
92  while (TopFreePart != NULL)
93  {
94  TopFreePart = (aux = TopFreePart)->Prev;
95  delete aux;
96  }
97  UsedInTop = Num;
98  SSize = 0;
99 }
100 
101 template <class Elem, int Num>
103 {
104  mfem::Swap(TopPart, other.TopPart);
105  mfem::Swap(TopFreePart, other.TopFreePart);
106  mfem::Swap(UsedInTop, other.UsedInTop);
107  mfem::Swap(SSize, other.SSize);
108 }
109 
110 template <class Elem, int Num>
112 {
113  size_t used_mem = 0;
114  StackPart <Elem, Num> *aux = TopPart;
115  while (aux != NULL)
116  {
117  used_mem += sizeof(StackPart <Elem, Num>);
118  aux = aux->Prev;
119  }
120  aux = TopFreePart;
121  while (aux != NULL)
122  {
123  used_mem += sizeof(StackPart <Elem, Num>);
124  aux = aux->Prev;
125  }
126  // Not counting sizeof(Stack <Elem, Num>)
127  return used_mem;
128 }
129 
130 
131 template <class Elem, int Num>
133 {
134 public:
136  Elem Elements[Num];
137 };
138 
139 template <class Elem, int Num>
140 class MemAlloc
141 {
142 private:
144  int AllocatedInLast;
145  Stack <Elem *, Num> UsedMem;
146 public:
147  MemAlloc() { Last = NULL; AllocatedInLast = Num; }
148  Elem *Alloc();
149  void Free (Elem *);
150  void Clear();
151  void Swap(MemAlloc<Elem, Num> &other);
152  size_t MemoryUsage() const;
153  ~MemAlloc() { Clear(); }
154 };
155 
156 template <class Elem, int Num>
158 {
160  if (UsedMem.Size() > 0)
161  {
162  return UsedMem.Pop();
163  }
164  if (AllocatedInLast == Num)
165  {
166  aux = Last;
167  Last = new MemAllocNode <Elem, Num>;
168  Last->Prev = aux;
169  AllocatedInLast = 0;
170  }
171  return &(Last->Elements[AllocatedInLast++]);
172 }
173 
174 template <class Elem, int Num>
176 {
177  UsedMem.Push (E);
178 }
179 
180 template <class Elem, int Num>
182 {
184  while (Last != NULL)
185  {
186  aux = Last->Prev;
187  delete Last;
188  Last = aux;
189  }
190  AllocatedInLast = Num;
191  UsedMem.Clear();
192 }
193 
194 template <class Elem, int Num>
196 {
197  mfem::Swap(Last, other.Last);
198  mfem::Swap(AllocatedInLast, other.AllocatedInLast);
199  UsedMem.Swap(other.UsedMem);
200 }
201 
202 template <class Elem, int Num>
204 {
205  size_t used_mem = UsedMem.MemoryUsage();
206  MemAllocNode <Elem, Num> *aux = Last;
207  while (aux != NULL)
208  {
209  used_mem += sizeof(MemAllocNode <Elem, Num>);
210  aux = aux->Prev;
211  }
212  // Not counting sizeof(MemAlloc <Elem, Num>)
213  return used_mem;
214 }
215 
216 }
217 
218 #endif
Elem * Alloc()
Definition: mem_alloc.hpp:157
Elem Elements[Num]
Definition: mem_alloc.hpp:26
void Free(Elem *)
Definition: mem_alloc.hpp:175
size_t MemoryUsage() const
Definition: mem_alloc.hpp:203
Elem Elements[Num]
Definition: mem_alloc.hpp:136
void Swap(Stack< Elem, Num > &other)
Definition: mem_alloc.hpp:102
size_t MemoryUsage() const
Definition: mem_alloc.hpp:111
StackPart< Elem, Num > * Prev
Definition: mem_alloc.hpp:25
int Size() const
Definition: mem_alloc.hpp:37
void Push(Elem E)
Definition: mem_alloc.hpp:47
Elem Pop()
Definition: mem_alloc.hpp:69
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:592
void Swap(MemAlloc< Elem, Num > &other)
Definition: mem_alloc.hpp:195
void Clear()
Definition: mem_alloc.hpp:84
MemAllocNode< Elem, Num > * Prev
Definition: mem_alloc.hpp:135