MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
mem_alloc.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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
18namespace mfem
19{
20
21template <class Elem, int Num>
23{
24public:
26 Elem Elements[Num];
27};
28
29template <class Elem, int Num>
30class Stack
31{
32private:
33 StackPart <Elem, Num> *TopPart, *TopFreePart;
34 int UsedInTop, SSize;
35public:
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
55template <class Elem, int Num>
57{
58 StackPart <Elem, Num> *aux;
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
77template <class Elem, int Num>
79{
80 StackPart <Elem, Num> *aux;
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
92template <class Elem, int Num>
94{
95 StackPart <Elem, Num> *aux;
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
110template <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
119template <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
140template <class Elem, int Num>
142{
143public:
144 MemAllocNode <Elem, Num> *Prev;
145 Elem Elements[Num];
146};
147
148template <class Elem, int Num>
150{
151private:
152 MemAllocNode <Elem, Num> *Last;
153 int AllocatedInLast;
154 Stack <Elem *, Num> UsedMem;
155public:
156 MemAlloc() { Last = NULL; AllocatedInLast = Num; }
157 Elem *Alloc();
158 void Free (Elem *);
159 void Clear();
161 size_t MemoryUsage() const;
163};
164
165template <class Elem, int Num>
167{
168 MemAllocNode <Elem, Num> *aux;
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
183template <class Elem, int Num>
185{
186 UsedMem.Push (E);
187}
188
189template <class Elem, int Num>
191{
192 MemAllocNode <Elem, Num> *aux;
193 while (Last != NULL)
194 {
195 aux = Last->Prev;
196 delete Last;
197 Last = aux;
198 }
199 AllocatedInLast = Num;
200 UsedMem.Clear();
201}
202
203template <class Elem, int Num>
205{
206 mfem::Swap(Last, other.Last);
207 mfem::Swap(AllocatedInLast, other.AllocatedInLast);
208 UsedMem.Swap(other.UsedMem);
209}
210
211template <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
MemAllocNode< Elem, Num > * Prev
void Swap(MemAlloc< Elem, Num > &other)
void Free(Elem *)
size_t MemoryUsage() const
Elem Elements[Num]
Definition mem_alloc.hpp:26
StackPart< Elem, Num > * Prev
Definition mem_alloc.hpp:25
void Push(Elem E)
Push element 'E' on the stack.
Definition mem_alloc.hpp:56
void Swap(Stack< Elem, Num > &other)
Swap the data in this stack with the data in other.
Stack()
Construct an empty stack.
Definition mem_alloc.hpp:37
void Clear()
Clear the elements off the stack.
Definition mem_alloc.hpp:93
int Size() const
Return the number of elements on the stack.
Definition mem_alloc.hpp:39
size_t MemoryUsage() const
Return the number of bytes used by the stack.
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:648