ATLAS Offline Software
Loading...
Searching...
No Matches
ArenaBlockAllocatorBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
11
15
16
17namespace SG {
18
19
26 : m_params (params),
27 m_blocks (nullptr),
28 m_freeblocks (nullptr),
29 m_stats(),
30 m_protected (false)
31{
32}
33
34
39{
40 // Should be called by the derived class dtor.
41 // Can't do it from here since it may call reset(), which is
42 // pure virtual in this class.
43 //erase();
44}
45
46
52 : m_params (other.m_params),
53 m_blocks (other.m_blocks),
55 m_stats (other.m_stats),
57{
58 other.m_blocks = nullptr;
59 other.m_freeblocks = nullptr;
60 other.m_stats.clear();
61 other.m_protected = false;
62}
63
64
69ArenaBlockAllocatorBase::operator=
71{
72 if (this != &other) {
73 erase();
74 m_params = other.m_params;
75 m_blocks = other.m_blocks;
76 m_freeblocks = other.m_freeblocks;
77 m_stats = other.m_stats;
78 m_protected = other.m_protected;
79 other.m_blocks = nullptr;
80 other.m_freeblocks = nullptr;
81 other.m_stats.clear();
82 other.m_protected = false;
83 }
84 return *this;
85}
86
87
92{
93 if (this != &other) {
94 std::swap (m_params, other.m_params);
95 std::swap (m_blocks, other.m_blocks);
96 std::swap (m_freeblocks, other.m_freeblocks);
97 std::swap (m_stats, other.m_stats);
98 std::swap (m_protected, other.m_protected);
99 }
100}
101
102
121{
122 if (m_protected) {
123 throw SG::ExcProtected();
124 }
125 if (size > m_stats.elts.total) {
126 // Growing the pool.
127 // Make a new block of the required size.
128 size_t sz = size - m_stats.elts.total;
129 ArenaBlock* newblock = ArenaBlock::newBlock (sz, m_params.eltSize,
130 m_params.constructor);
131
132 // Update statistics (others are derived in stats()).
133 ++m_stats.blocks.free;
134 ++m_stats.blocks.total;
135 m_stats.elts.total += newblock->size();
136
137 // Add to the free list.
138 newblock->link() = m_freeblocks;
139 m_freeblocks = newblock;
140 }
141 else {
142 // Shrinking the pool.
143 // Loop while we can get rid of the first free block.
144 while (size < m_stats.elts.total &&
145 m_freeblocks &&
146 m_freeblocks->size() <= (m_stats.elts.total - size))
147 {
148 // Remove it from the free list.
150 m_freeblocks = m_freeblocks->link();
151
152 // Update statistics (others are derived in stats()).
153 m_stats.elts.total -= p->size();
154 --m_stats.blocks.free;
155 --m_stats.blocks.total;
156
157 // Free the block.
158 ArenaBlock::destroy (p, m_params.destructor);
159 }
160 }
161}
162
163
173{
174 if (m_protected) {
175 throw SG::ExcProtected();
176 }
178}
179
180
187{
188 // Do we need to run clear() on the allocated elements?
189 // If so, do so via reset().
190 if (m_params.mustClear && m_params.clear) {
191 reset();
192 }
193
194 // Kill the block lists (both free and in use).
197 m_blocks = m_freeblocks = nullptr;
198
199 // Reset statistics.
200 m_stats.clear();
201}
202
203
208{
209 // Calculate derived statistics.
211 stats.elts.free = stats.elts.total - stats.elts.inuse;
212 stats.bytes.inuse = stats.elts.inuse * m_params.eltSize +
213 stats.blocks.inuse * ArenaBlock::overhead();
214 stats.bytes.total = stats.elts.total * m_params.eltSize +
215 stats.blocks.total * ArenaBlock::overhead();
216 stats.bytes.free = stats.elts.free * m_params.eltSize +
217 stats.blocks.free * ArenaBlock::overhead();
218 return stats;
219}
220
221
225const std::string& ArenaBlockAllocatorBase::name() const
226{
227 return m_params.name;
228}
229
230
236{
237 return m_params;
238}
239
240
246{
247 if (m_protected) {
248 throw SG::ExcProtected();
249 }
250
251 ArenaBlock* newblock = m_freeblocks;
252 if (newblock) {
253 // There's something on the free list. Remove it and update statistics.
254 m_freeblocks = newblock->link();
255 --m_stats.blocks.free;
256 }
257 else {
258 // Otherwise, we need to make a new block.
259 newblock = ArenaBlock::newBlock (m_params.nblock, m_params.eltSize,
260 m_params.constructor);
261 m_stats.elts.total += newblock->size();
262 ++m_stats.blocks.total;
263 }
264 // Finish updating statistics.
265 // (Remaining ones are computed in stats().)
266 ++m_stats.blocks.inuse;
267
268 // Link it into the in-use list and return.
269 newblock->link() = m_blocks;
270 m_blocks = newblock;
271 return newblock;
272}
273
274
286
287
301
302
303} // namespace SG
Common functionality for block-oriented allocators.
A large memory block that gets carved into smaller uniform elements. See Arena.h for an overview of t...
Exceptions that can be thrown from AthAllocators.
static Double_t sz
virtual void reset()=0
Free all allocated elements.
Common functionality for block-oriented allocators.
virtual void reserve(size_t size) override
Set the total number of elements cached by the allocator.
void unprotect()
Write-enable the memory managed by this allocator.
const Params & params() const
Return this Allocator's parameters.
ArenaBlock * getBlock()
Return an empty block, either newly-allocated or from the free list.
virtual void erase() override
Free all allocated elements and release memory back to the system.
virtual ~ArenaBlockAllocatorBase()
Destructor.
void eraseUnprotected()
Free all allocated elements and release memory back to the system.
ArenaAllocatorBase::Stats m_stats
The statistics structure.
void swap(ArenaBlockAllocatorBase &other)
Swap.
ArenaBlockAllocatorBase(const Params &params)
Constructor.
void protect()
Write-protect the memory managed by this allocator.
ArenaBlock * m_blocks
The list of blocks currently in use.
virtual Stats stats() const override
Return the statistics block for this allocator.
Params m_params
The parameters for this allocator.
virtual const std::string & name() const override
Return the name of this allocator.
ArenaBlock * m_freeblocks
The list of free blocks.
bool m_protected
Flag whether the arena has been protected.
A large memory block that gets carved into smaller uniform elements.
Definition ArenaBlock.h:43
static void protectList(ArenaBlock *p)
Write-protect all blocks in a list.
static void destroyList(ArenaBlock *p, func_t *dtor)
Destroy all blocks in a list.
static void destroy(ArenaBlock *p, func_t *dtor)
Destroy a block.
static ArenaBlock * newBlock(size_t n, size_t elt_size, func_t *ctor)
Create a new block.
ArenaBlock *& link()
Return the link pointer of the block.
static void unprotectList(ArenaBlock *p)
Write-enable all blocks in a list.
size_t size() const
Return the number of elements in the block.
static size_t overhead()
Return the per-block memory overhead, in bytes.
Exception — Attempt to change protected arena.
Forward declaration.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
Statistics for an allocator.