ATLAS Offline Software
ArenaPoolAllocator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
15 #include <cassert>
16 
17 
18 namespace SG {
19 
20 
26 inline
29  ArenaBlock* & block)
30 {
31  // If we haven't yet reached the start of this block, move the iterator
32  // back one.
33  if (base > block->index(0,0)) {
34  return base - block->eltSize();
35  }
36 
37  // Move to the previous block.
38  block = block->link();
39  if (block) {
40  return block->index (block->size()-1, block->eltSize());
41  }
42  return nullptr;
43 }
44 
45 
51 inline
54  const ArenaBlock* & block)
55 {
56  // If we haven't yet reached the start of this block, move the iterator
57  // back one.
58  if (base > block->index(0,0)) {
59  return base - block->eltSize();
60  }
61 
62  // Move to the previous block.
63  block = block->link();
64  if (block) {
65  return block->index (block->size()-1, block->eltSize());
66  }
67  return nullptr;
68 }
69 
70 
75 {
76  this->base_reference() =
77  ArenaPoolAllocator_iterator_increment (this->base_reference(), m_block);
78 }
79 
80 
85 {
86  ArenaPoolAllocator::const_pointer base = this->base_reference();
88  this->base_reference() = base;
89 }
90 
91 
99  m_ptr (nullptr),
100  m_end (nullptr)
101 {
102 }
103 
104 
109 {
110  if (m_protected) {
111  try {
112  unprotect();
113  }
114  catch (const SG::ExcProtection&) {
115  // Got an error from mprotect...
116  std::abort();
117  }
118  }
120 }
121 
122 
128  : ArenaBlockAllocatorBase (std::move (other)),
129  m_ptr (other.m_ptr),
130  m_end (other.m_end)
131 {
132  // False positives
133  // cppcheck-suppress useInitializationList
134  other.m_ptr = nullptr;
135  // cppcheck-suppress useInitializationList
136  other.m_end = nullptr;
137 }
138 
139 
144 ArenaPoolAllocator::operator=
146 {
147  if (this != &other) {
149  m_ptr = other.m_ptr;
150  m_end = other.m_end;
151  other.m_ptr = nullptr;
152  other.m_end = nullptr;
153  }
154  return *this;
155 }
156 
157 
162 {
163  if (this != &other) {
165  std::swap (m_ptr, other.m_ptr);
166  std::swap (m_end, other.m_end);
167  }
168 }
169 
170 
180 {
181  // Clear each block in turn.
182  while (m_blocks) {
183  clearBlock();
184  }
185 
186  // Check that things are consistent.
187  assert (m_stats.elts.inuse == 0);
188  assert (m_ptr == nullptr);
189  assert (m_end == nullptr);
190 }
191 
192 
202 {
203  // Delete all the blocks.
205 
206  // Reset pointers.
207  m_ptr = m_end = nullptr;
208 }
209 
210 
219 {
220  // Clear the topmost block, as long as it doesn't contain the sought-after
221  // pointer.
222  ArenaBlock* p = m_blocks;
223  assert (p != nullptr);
224  size_t elt_size = p->eltSize();
225  while (p && !(blk >= p->index(0, elt_size) &&
226  blk < p->index(p->size(), elt_size)))
227  {
228  clearBlock();
229  p = m_blocks;
230  }
231 
232  // We'll trip this if the supplied pointer wasn't in any block.
233  assert (p != nullptr);
234 
235  // If the element is at the beginning of this block, just clear the whole
236  // thing.
237  if (blk == p->index(0, elt_size)) {
238  clearBlock();
239  }
240  else {
241  // Otherwise, we need to clear some of the elements in this block.
242  // See if we need to call @c clear.
244  if (clear) {
245  // Yeah, we do. Call @c clear on each element in turn.
246  while (m_ptr > blk) {
247  m_ptr -= elt_size;
248  clear (m_ptr);
249  --m_stats.elts.inuse;
250  }
251  // We'll trip this if the supplied pointer wasn't on an element
252  // boundary.
253  assert (m_ptr == blk);
254  }
255  else {
256  // We don't need to call @c clear.
257  // So we can do it the fast way --- just reset pointers.
258  m_stats.elts.inuse -= (m_ptr - blk) / elt_size;
259  m_ptr = blk;
260  }
261  }
262 }
263 
264 
272 {
273  // If @c m_ptr is one set, it is one more than the last allocated element.
274  return iterator (m_ptr ? m_ptr - m_params.eltSize : nullptr, m_blocks);
275 }
276 
277 
285 {
286  // If @c m_ptr is one set, it is one more than the last allocated element.
287  return const_iterator (m_ptr ? m_ptr - m_params.eltSize : nullptr, m_blocks);
288 }
289 
290 
295 {
296  // Use a null iterator to signal the end.
297  return iterator ();
298 }
299 
300 
305 {
306  // Use a null iterator to signal the end.
307  return const_iterator ();
308 }
309 
310 
315 {
316  // Get a new block.
317  ArenaBlock* newblock = getBlock();
318 
319  // Set the pointers.
320  m_ptr = newblock->index (0, m_params.eltSize);
321  m_end = newblock->index (newblock->size(), m_params.eltSize);
322 }
323 
324 
330 {
331  // The topmost block.
332  ArenaBlock* p = m_blocks;
333 
334  // Nothing to do if there are no allocated blocks!
335  if (!p) return;
336 
337  size_t elt_size = p->eltSize();
338 
339  // The first element of the block.
340  pointer base = p->index(0, elt_size);
341 
342  // Do we need to call @c clear? If so, call it on all allocated elements
343  // in this block.
345  if (clear) {
346  pointer elt = base;
347  while (elt < m_ptr) {
348  clear (elt);
349  elt += elt_size;
350  }
351  }
352 
353  // Update statistics.
354  --m_stats.blocks.inuse;
355  ++m_stats.blocks.free;
356  m_stats.elts.inuse -= (m_ptr - base) / elt_size;
357 
358  // Move the block from the allocated to the free list.
359  m_blocks = p->link();
360  p->link() = m_freeblocks;
361  m_freeblocks = p;
362  p = m_blocks;
363 
364  // Reset the pointers.
365  if (p) {
366  m_ptr = m_end = p->index(p->size());
367  }
368  else {
369  m_ptr = m_end = nullptr;
370  }
371 }
372 
373 
374 } // namespace SG
SG::ArenaBlockAllocatorBase::params
const Params & params() const
Return this Allocator's parameters.
Definition: ArenaBlockAllocatorBase.cxx:235
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
base
std::string base
Definition: hcg.cxx:78
SG::ArenaPoolAllocator::refill
void refill()
Add more free elements to the pool.
Definition: ArenaPoolAllocator.cxx:314
SG::ArenaBlockAllocatorBase::m_blocks
ArenaBlock * m_blocks
The list of blocks currently in use.
Definition: ArenaBlockAllocatorBase.h:161
SG::ExcProtection
Exception — Attempt to change memory protection failed.
Definition: Control/AthAllocators/AthAllocators/exceptions.h:43
SG::ArenaBlock::index
pointer index(size_t i)
Return a pointer to element i in the block.
SG::ArenaPoolAllocator
Pool-based allocator.
Definition: ArenaPoolAllocator.h:40
SG::ArenaPoolAllocator::resetTo
void resetTo(pointer p)
Reset pool back to a previous state.
Definition: ArenaPoolAllocator.cxx:218
SG::ArenaBlockAllocatorBase::getBlock
ArenaBlock * getBlock()
Return an empty block, either newly-allocated or from the free list.
Definition: ArenaBlockAllocatorBase.cxx:245
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::ArenaPoolAllocator::const_iterator::increment
void increment()
Move the iterator forward.
Definition: ArenaPoolAllocator.cxx:84
index
Definition: index.py:1
SG::ArenaBlockAllocatorBase::m_params
Params m_params
The parameters for this allocator.
Definition: ArenaBlockAllocatorBase.h:158
SG::ArenaBlock::eltSize
size_t eltSize() const
Return the size of the elements in the block.
SG::ArenaBlockAllocatorBase::erase
virtual void erase() override
Free all allocated elements and release memory back to the system.
Definition: ArenaBlockAllocatorBase.cxx:172
SG::ArenaAllocatorBase::Stats::Stat::free
size_t free
Number of items currently not allocated by the application but cached by the allocator.
Definition: ArenaAllocatorBase.h:205
SG::ArenaAllocatorBase::Params::clear
func_t * clear
Clear function for elements.
Definition: ArenaAllocatorBase.h:175
SG::ArenaBlockAllocatorBase::m_protected
bool m_protected
Flag whether the arena has been protected.
Definition: ArenaBlockAllocatorBase.h:170
SG::ArenaPoolAllocator::swap
void swap(ArenaPoolAllocator &other)
Swap.
Definition: ArenaPoolAllocator.cxx:161
SG::ArenaAllocatorBase::Stats::Stat::inuse
size_t inuse
Number of items currently allocated by the application.
Definition: ArenaAllocatorBase.h:202
SG::ArenaAllocatorBase::Stats::blocks
Stat blocks
Counts of blocks.
Definition: ArenaAllocatorBase.h:217
SG::ArenaBlock::link
ArenaBlock *& link()
Return the link pointer of the block.
SG::ArenaAllocatorBase::func_t
void func_t(pointer)
Type of functions for constructor, etc.
Definition: ArenaAllocatorBase.h:143
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
SG::ArenaPoolAllocator_iterator_increment
ArenaPoolAllocator::pointer ArenaPoolAllocator_iterator_increment(ArenaPoolAllocator::pointer base, ArenaBlock *&block)
Helper: common code for advancing an iterator.
Definition: ArenaPoolAllocator.cxx:28
SG::ArenaPoolAllocator::m_end
pointer m_end
One past the last available element in the current block, of null.
Definition: ArenaPoolAllocator.h:265
SG::ArenaPoolAllocator::clearBlock
void clearBlock()
Reset all elements in the topmost block, and move the block to the free list.
Definition: ArenaPoolAllocator.cxx:329
SG::ArenaBlock::size
size_t size() const
Return the number of elements in the block.
SG::ArenaPoolAllocator::m_ptr
pointer m_ptr
Pointer to the next free element to allocate, or null.
Definition: ArenaPoolAllocator.h:262
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
SG::ArenaBlockAllocatorBase::eraseUnprotected
void eraseUnprotected()
Free all allocated elements and release memory back to the system.
Definition: ArenaBlockAllocatorBase.cxx:186
SG::ArenaBlockAllocatorBase
Common functionality for block-oriented allocators.
Definition: ArenaBlockAllocatorBase.h:35
SG::ArenaPoolAllocator::iterator
Non-const iterator for the pool.
Definition: ArenaPoolAllocator.h:59
SG::ArenaPoolAllocator::iterator::m_block
ArenaBlock * m_block
Block containing the current element.
Definition: ArenaPoolAllocator.h:81
SG::ArenaBlock
A large memory block that gets carved into smaller uniform elements.
Definition: ArenaBlock.h:43
SG::ArenaPoolAllocator::begin
iterator begin()
Starting pool iterator.
Definition: ArenaPoolAllocator.cxx:271
ArenaPoolAllocator.h
Pool-based allocator. See Arena.h for an overview of the arena-based memory allocators.
SG::ArenaPoolAllocator::reset
virtual void reset() override
Free all allocated elements.
Definition: ArenaPoolAllocator.cxx:179
SG::ArenaBlockAllocatorBase::operator=
ArenaBlockAllocatorBase & operator=(const ArenaBlockAllocatorBase &)=delete
SG::ArenaPoolAllocator::iterator::increment
void increment()
Move the iterator forward.
Definition: ArenaPoolAllocator.cxx:74
SG::ArenaPoolAllocator::erase
virtual void erase() override final
Free all allocated elements and release memory back to the system.
Definition: ArenaPoolAllocator.cxx:201
SG::ArenaPoolAllocator::ArenaPoolAllocator
ArenaPoolAllocator(const Params &params)
Constructor.
Definition: ArenaPoolAllocator.cxx:97
SG::ArenaAllocatorBase::const_pointer
const char * const_pointer
And a const version of the pointer.
Definition: ArenaAllocatorBase.h:140
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
SG::ArenaBlockAllocatorBase::m_stats
ArenaAllocatorBase::Stats m_stats
The statistics structure.
Definition: ArenaBlockAllocatorBase.h:167
SG::ArenaBlockAllocatorBase::unprotect
void unprotect()
Write-enable the memory managed by this allocator.
Definition: ArenaBlockAllocatorBase.cxx:294
SG::ArenaPoolAllocator::~ArenaPoolAllocator
virtual ~ArenaPoolAllocator()
Destructor.
Definition: ArenaPoolAllocator.cxx:108
SG::ArenaBlockAllocatorBase::swap
void swap(ArenaBlockAllocatorBase &other)
Swap.
Definition: ArenaBlockAllocatorBase.cxx:91
SG::ArenaBlockAllocatorBase::m_freeblocks
ArenaBlock * m_freeblocks
The list of free blocks.
Definition: ArenaBlockAllocatorBase.h:164
SG::ArenaAllocatorBase::Params::eltSize
size_t eltSize
The size in bytes of the individual elements we're allocating.
Definition: ArenaAllocatorBase.h:155
SG::ArenaAllocatorBase::pointer
char * pointer
Type for pointers to elements.
Definition: ArenaAllocatorBase.h:137
exceptions.h
Exceptions that can be thrown from AthAllocators.
SG::ArenaPoolAllocator::end
iterator end()
Ending pool iterator.
Definition: ArenaPoolAllocator.cxx:294
SG::ArenaPoolAllocator::const_iterator
Const iterator for the pool.
Definition: ArenaPoolAllocator.h:105
SG::ArenaAllocatorBase::Params
Allocator parameters.
Definition: ArenaAllocatorBase.h:150
ArenaBlock.h
A large memory block that gets carved into smaller uniform elements. See Arena.h for an overview of t...
SG::ArenaAllocatorBase::Stats::elts
Stat elts
Counts of elements.
Definition: ArenaAllocatorBase.h:219