ATLAS Offline Software
ArenaPoolAllocator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
14 #include <cassert>
15 
16 
17 namespace SG {
18 
19 
25 inline
28  ArenaBlock* & block)
29 {
30  // If we haven't yet reached the start of this block, move the iterator
31  // back one.
32  if (base > block->index(0,0)) {
33  return base - block->eltSize();
34  }
35 
36  // Move to the previous block.
37  block = block->link();
38  if (block) {
39  return block->index (block->size()-1, block->eltSize());
40  }
41  return nullptr;
42 }
43 
44 
50 inline
53  const ArenaBlock* & block)
54 {
55  // If we haven't yet reached the start of this block, move the iterator
56  // back one.
57  if (base > block->index(0,0)) {
58  return base - block->eltSize();
59  }
60 
61  // Move to the previous block.
62  block = block->link();
63  if (block) {
64  return block->index (block->size()-1, block->eltSize());
65  }
66  return nullptr;
67 }
68 
69 
74 {
75  this->base_reference() =
76  ArenaPoolAllocator_iterator_increment (this->base_reference(), m_block);
77 }
78 
79 
84 {
85  ArenaPoolAllocator::const_pointer base = this->base_reference();
87  this->base_reference() = base;
88 }
89 
90 
98  m_ptr (nullptr),
99  m_end (nullptr)
100 {
101 }
102 
103 
108 {
109  erase();
110 }
111 
112 
118  : ArenaBlockAllocatorBase (std::move (other)),
119  m_ptr (other.m_ptr),
120  m_end (other.m_end)
121 {
122  // False positives
123  // cppcheck-suppress useInitializationList
124  other.m_ptr = nullptr;
125  // cppcheck-suppress useInitializationList
126  other.m_end = nullptr;
127 }
128 
129 
134 ArenaPoolAllocator::operator=
136 {
137  if (this != &other) {
139  m_ptr = other.m_ptr;
140  m_end = other.m_end;
141  other.m_ptr = nullptr;
142  other.m_end = nullptr;
143  }
144  return *this;
145 }
146 
147 
152 {
153  if (this != &other) {
155  std::swap (m_ptr, other.m_ptr);
156  std::swap (m_end, other.m_end);
157  }
158 }
159 
160 
170 {
171  // Clear each block in turn.
172  while (m_blocks) {
173  clearBlock();
174  }
175 
176  // Check that things are consistent.
177  assert (m_stats.elts.inuse == 0);
178  assert (m_ptr == nullptr);
179  assert (m_end == nullptr);
180 }
181 
182 
192 {
193  // Delete all the blocks.
195 
196  // Reset pointers.
197  m_ptr = m_end = nullptr;
198 }
199 
200 
209 {
210  // Clear the topmost block, as long as it doesn't contain the sought-after
211  // pointer.
212  ArenaBlock* p = m_blocks;
213  assert (p != nullptr);
214  size_t elt_size = p->eltSize();
215  while (p && !(blk >= p->index(0, elt_size) &&
216  blk < p->index(p->size(), elt_size)))
217  {
218  clearBlock();
219  p = m_blocks;
220  }
221 
222  // We'll trip this if the supplied pointer wasn't in any block.
223  assert (p != nullptr);
224 
225  // If the element is at the beginning of this block, just clear the whole
226  // thing.
227  if (blk == p->index(0, elt_size)) {
228  clearBlock();
229  }
230  else {
231  // Otherwise, we need to clear some of the elements in this block.
232  // See if we need to call @c clear.
234  if (clear) {
235  // Yeah, we do. Call @c clear on each element in turn.
236  while (m_ptr > blk) {
237  m_ptr -= elt_size;
238  clear (m_ptr);
239  --m_stats.elts.inuse;
240  }
241  // We'll trip this if the supplied pointer wasn't on an element
242  // boundary.
243  assert (m_ptr == blk);
244  }
245  else {
246  // We don't need to call @c clear.
247  // So we can do it the fast way --- just reset pointers.
248  m_stats.elts.inuse -= (m_ptr - blk) / elt_size;
249  m_ptr = blk;
250  }
251  }
252 }
253 
254 
262 {
263  // If @c m_ptr is one set, it is one more than the last allocated element.
264  return iterator (m_ptr ? m_ptr - m_params.eltSize : nullptr, m_blocks);
265 }
266 
267 
275 {
276  // If @c m_ptr is one set, it is one more than the last allocated element.
277  return const_iterator (m_ptr ? m_ptr - m_params.eltSize : nullptr, m_blocks);
278 }
279 
280 
285 {
286  // Use a null iterator to signal the end.
287  return iterator ();
288 }
289 
290 
295 {
296  // Use a null iterator to signal the end.
297  return const_iterator ();
298 }
299 
300 
305 {
306  // Get a new block.
307  ArenaBlock* newblock = getBlock();
308 
309  // Set the pointers.
310  m_ptr = newblock->index (0, m_params.eltSize);
311  m_end = newblock->index (newblock->size(), m_params.eltSize);
312 }
313 
314 
320 {
321  // The topmost block.
322  ArenaBlock* p = m_blocks;
323 
324  // Nothing to do if there are no allocated blocks!
325  if (!p) return;
326 
327  size_t elt_size = p->eltSize();
328 
329  // The first element of the block.
330  pointer base = p->index(0, elt_size);
331 
332  // Do we need to call @c clear? If so, call it on all allocated elements
333  // in this block.
335  if (clear) {
336  pointer elt = base;
337  while (elt < m_ptr) {
338  clear (elt);
339  elt += elt_size;
340  }
341  }
342 
343  // Update statistics.
344  --m_stats.blocks.inuse;
345  ++m_stats.blocks.free;
346  m_stats.elts.inuse -= (m_ptr - base) / elt_size;
347 
348  // Move the block from the allocated to the free list.
349  m_blocks = p->link();
350  p->link() = m_freeblocks;
351  m_freeblocks = p;
352  p = m_blocks;
353 
354  // Reset the pointers.
355  if (p) {
356  m_ptr = m_end = p->index(p->size());
357  }
358  else {
359  m_ptr = m_end = nullptr;
360  }
361 }
362 
363 
364 } // namespace SG
SG::ArenaBlockAllocatorBase::params
const Params & params() const
Return this Allocator's parameters.
Definition: ArenaBlockAllocatorBase.cxx:224
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:304
SG::ArenaBlockAllocatorBase::m_blocks
ArenaBlock * m_blocks
The list of blocks currently in use.
Definition: ArenaBlockAllocatorBase.h:153
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:208
SG::ArenaBlockAllocatorBase::getBlock
ArenaBlock * getBlock()
Return an empty block, either newly-allocated or from the free list.
Definition: ArenaBlockAllocatorBase.cxx:234
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::ArenaPoolAllocator::const_iterator::increment
void increment()
Move the iterator forward.
Definition: ArenaPoolAllocator.cxx:83
index
Definition: index.py:1
SG::ArenaBlockAllocatorBase::m_params
Params m_params
The parameters for this allocator.
Definition: ArenaBlockAllocatorBase.h:150
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::ArenaPoolAllocator::swap
void swap(ArenaPoolAllocator &other)
Swap.
Definition: ArenaPoolAllocator.cxx:151
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:210
SG::ArenaPoolAllocator_iterator_increment
ArenaPoolAllocator::pointer ArenaPoolAllocator_iterator_increment(ArenaPoolAllocator::pointer base, ArenaBlock *&block)
Helper: common code for advancing an iterator.
Definition: ArenaPoolAllocator.cxx:27
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:319
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
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:261
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:169
SG::ArenaBlockAllocatorBase::operator=
ArenaBlockAllocatorBase & operator=(const ArenaBlockAllocatorBase &)=delete
SG::ArenaPoolAllocator::iterator::increment
void increment()
Move the iterator forward.
Definition: ArenaPoolAllocator.cxx:73
SG::ArenaPoolAllocator::erase
virtual void erase() override final
Free all allocated elements and release memory back to the system.
Definition: ArenaPoolAllocator.cxx:191
SG::ArenaPoolAllocator::ArenaPoolAllocator
ArenaPoolAllocator(const Params &params)
Constructor.
Definition: ArenaPoolAllocator.cxx:96
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:159
SG::ArenaPoolAllocator::~ArenaPoolAllocator
virtual ~ArenaPoolAllocator()
Destructor.
Definition: ArenaPoolAllocator.cxx:107
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:156
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
SG::ArenaPoolAllocator::end
iterator end()
Ending pool iterator.
Definition: ArenaPoolAllocator.cxx:284
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