forked from applied-numerical-algorithms-group-lbnl/Chombo_4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChombo_Pool.H
179 lines (136 loc) · 4.93 KB
/
Chombo_Pool.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#ifdef CH_LANG_CC
/*
* _______ __
* / ___/ / ___ __ _ / / ___
* / /__/ _ \/ _ \/ V \/ _ \/ _ \
* \___/_//_/\___/_/_/_/_.__/\___/
* Please refer to Copyright.txt, in Chombo's root directory.
*/
#endif
#ifndef _Chombo_POOL_H_
#define _Chombo_POOL_H_
#include <cstdlib>
#include <list>
#include <vector>
#include "Chombo_BaseNamespaceHeader.H"
class Pool;
typedef std::list<Pool*> PoolList;
/// Pool is a class to optimize memory allocation.
/**
Pool is a class to optimize memory allocation. It is specialized to
allocate fixed size chunks of memory specified by ptrSize in the
constructor. Its operation is analogous to malloc, not new. It
does not initialize the memory in any way. The constructor can
optionally specify an initial pool size, and memory alignment. The
pool size will grow as needed by calling ::new. The pool size never
shrinks. Memory will be reclaimed at ~Pool(). The units of poolSize
are number-of-ptrSize-chunks. The units of alignment are bytes.
Pool can only be used for objects of fixed size. Typically used in
situations where a class or struct is being constantly constructed and
deleted. Objects returned by value from functions, elements in a database,
etc. Pool's tend to be allocated statically.
(from Copier.cpp)
\code
// static data member s_motionIemPool getting constructed
Pool Copier::s_motionItemPool(sizeof(MotionItem), "Copier::MotionItem");
// note the use of a 'placement new'
MotionItem* item = new (s_motionItemPool.getPtr()) MotionItem(fromdi, todi, box);
// if your object does requires it's destructor to be called.
item->~MotionItem();
// then return the memory chunk to your pool
s_motionItemPool.returnPtr(item)
\endcode
Technical note
In the event of multi-threading Chombo, we will have to make
pool access serialized (locks, single thread access, etc) or implement a
fast lock-free version, or go back to new/delete and let the OS be clever
again about memory management.
*/
class Pool
{
public:
///
/**
@param a_ptrSize Size of fixed memory allocations needed
@param a_poolSize Size of allocations (a_ptrSize*a_poolSize) made
of the operating system. This controls the granularity of the
Pool allocations. Smaller values result in less wasted memory,
at the cost of more calls to the operating system for heap memory.
@param a_name optional name for this Pool. Used in reporting memory
by the memory tracking system in Chombo.
*/
Pool(int a_ptrSize,
const char* a_name = "unnamed",
int a_poolSize = 100,
int a_alignment = sizeof(int),
bool a_allowUnalignedAlloc = false);
///
~Pool();
/// request a section of memory of ptrSize_ contiguous bytes.
inline void* getPtr();
/// return memory previous acquired with the getPtr() function.
void returnPtr(void* a_ptr);
/// report how much memory this Pool is currently using.
/**
memUsage for a Pool only grows until Pool destruction. The Pool
object has no knowledge of what pieces of memory it has parcelled out
to a user, so it keeps it all available. The user is responsible for
not leaking Pool memory.
*/
long memUsage() const;
/**
undocumented function, call this at own risk. You must
be absolutely positive that you have returned all the
ptr's you've asked for, or you can have major seg faults.
*/
void clear();
// not for public consumption. used in memory tracking code.
static PoolList* m_poolList_;
char m_name_[64];
protected:
private:
///
std::vector<char*> m_pool_;
///
int m_ptrSize_;
///
int m_poolSize_;
///
int m_alignment_;
bool m_allowUnalignedAlloc; ///< T - Allows unaligned allocations
///< (> sizof(double) if it is not
///< known how to allocate aligned
///< memory
///< F - Otherwise abort
///
void* m_next_;
///
void* getMoreMemory();
void* getMore();
///
/// Not implemented. Compiler will not let you copy a Pool
Pool(const Pool& a_rhs);
/// Not implemented. Compiler will not let you copy a Pool
const Pool& operator = (const Pool& a_rhs);
static void clearAllPools();
friend void dumpmemoryatexit();
};
/// getPtr and returnPtr must be as fast as possible!
inline void* Pool::getPtr()
{
#ifdef _OPENMP
return malloc(m_ptrSize_);
#else
if (m_next_ == 0)
{
m_next_ = getMoreMemory();
}
void* result = m_next_; // result points to first free chunk in list
m_next_ = *(void**)m_next_; // point m_next_ to next free chunk in list.
return result;
#endif
}
// Stroustrup (S. 11.5.1) says a declaration in the global scope is needed
void dumpmemoryatexit();
#include "Chombo_BaseNamespaceFooter.H"
#endif