ATLAS Offline Software
Loading...
Searching...
No Matches
ArenaHeapAllocator.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#include <vector>
16#include <algorithm>
17#include <cassert>
18
19
20namespace SG {
21
22
30 m_freeptr (nullptr)
31{
32 // Consistency check.
33 assert (params.linkOffset + sizeof (pointer) <= params.eltSize);
34}
35
36
41{
42 if (m_protected) {
43 try {
44 unprotect();
45 }
46 catch (const SG::ExcProtection&) {
47 // Got an error from mprotect...
48 std::abort();
49 }
50 }
52}
53
54
59 (ArenaHeapAllocator&& other)
60 : ArenaBlockAllocatorBase (std::move (other)),
61 m_freeptr (other.m_freeptr)
62{
63 // False positives
64 // cppcheck-suppress useInitializationList
65 other.m_freeptr = nullptr;
66}
67
68
73ArenaHeapAllocator::operator=
74 (ArenaHeapAllocator&& other)
75{
76 if (this != &other) {
77 ArenaBlockAllocatorBase::operator= (std::move (other));
78 m_freeptr = other.m_freeptr;
79 other.m_freeptr = nullptr;
80 }
81 return *this;
82}
83
84
89{
90 if (this != &other) {
92 std::swap (m_freeptr, other.m_freeptr);
93 }
94}
95
96
106{
107 if (!m_blocks) return;
108 if (m_params.clear) {
109 if (m_params.canReclear || m_freeptr == nullptr) {
110 // Just call clear() on all blocks --- allocated or not.
112 }
113 else {
114 // We can only call clear() on allocated blocks.
115 slowClear();
116 }
117 }
118
119 // Move all blocks back to the free list.
121
122 // Reset state.
123 m_blocks = nullptr;
124 m_freeptr = nullptr;
125 m_stats.elts.inuse = 0;
126 m_stats.blocks.free += m_stats.blocks.inuse;
127 m_stats.blocks.inuse = 0;
128}
129
130
144
145
150{
151 // Get a new block.
152 ArenaBlock* newblock = getBlock();
153
154 // Set up the links for the new free elements.
155 pointer lastelt = nullptr;
156 size_t sz = newblock->size();
157 size_t elt_size = newblock->eltSize();
158 for (size_t i=1; i < sz; i++) {
159 pointer elt = newblock->index (i, elt_size);
160 link(elt) = lastelt;
161 lastelt = elt;
162 }
163 // Set the free pointer to the next-to-last one.
164 m_freeptr = newblock->index (sz-1, elt_size);
165
166 // And return the last one.
167 return newblock->index (0, elt_size);
168}
169
170
175{
176 // Make a list of all free elements, in sorted order.
177 std::vector<pointer> free_ptrs;
178 free_ptrs.reserve (m_stats.elts.total - m_stats.elts.inuse);
179 for (pointer p = m_freeptr; p; p = link(p)) {
180 free_ptrs.push_back (p);
181 }
182 std::sort (free_ptrs.begin(), free_ptrs.end());
183
184 // Make a list of all used blocks, in sorted order.
185 std::vector<ArenaBlock*> blocks;
186 for (ArenaBlock* p = m_blocks; p; p = p->link()) {
187 blocks.push_back (p);
188 }
189 std::sort (blocks.begin(), blocks.end());
190
191 // Walk through both of these lists.
192 // For each block, walk through its elements, and call @c clear
193 // for those not on the free list.
194 std::vector<pointer>::iterator pi = free_ptrs.begin();
195 std::vector<pointer>::iterator pi_end = free_ptrs.end();
196 std::vector<ArenaBlock*>::iterator bi = blocks.begin();
197 std::vector<ArenaBlock*>::iterator bi_end = blocks.end();
198 func_t* clear = m_params.clear;
199 for (; bi != bi_end; ++bi) {
200 ArenaBlock& bl = **bi;
201 size_t sz = bl.size();
202 size_t elt_size = bl.eltSize();
203 for (size_t i = 0; i < sz; i++) {
204 pointer ptr = bl.index (i, elt_size);
205 if (pi != pi_end && ptr == *pi) {
206 ++pi;
207 }
208 else {
209 clear (ptr);
210 }
211 }
212 }
213}
214
215
216} // namespace SG
A large memory block that gets carved into smaller uniform elements. See Arena.h for an overview of t...
Heap-based allocator. See Arena.h for an overview of the arena-based memory allocators.
Exceptions that can be thrown from AthAllocators.
static Double_t sz
#define pi
char * pointer
Type for pointers to elements.
void func_t(pointer)
Type of functions for constructor, etc.
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.
ArenaBlockAllocatorBase & operator=(const ArenaBlockAllocatorBase &)=delete
virtual void erase() override
Free all allocated elements and release memory back to the system.
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.
ArenaBlock * m_blocks
The list of blocks currently in use.
Params m_params
The parameters for 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
pointer index(size_t i)
Return a pointer to element i in the block.
size_t eltSize() const
Return the size of the elements in the block.
static void appendList(ArenaBlock **headp, ArenaBlock *tail)
Concatenate two lists of blocks.
size_t size() const
Return the number of elements in the block.
static void applyList(ArenaBlock *p, func_t *func, size_t n)
Call a function on elements in a list of blocks.
Heap-based allocator.
virtual ~ArenaHeapAllocator()
Destructor.
void swap(ArenaHeapAllocator &other)
Swap.
pointer refill()
Add more free elements to the pool, and allocate a new element.
void slowClear()
Call clear() for all allocated elements.
pointer m_freeptr
Pointer to the next free element.
pointer & link(pointer p) const
Return a reference to the link for an element.
virtual void erase() override final
Free all allocated elements and release memory back to the system.
virtual void reset() override
Free all allocated elements.
ArenaHeapAllocator(const Params &params)
Constructor.
Exception — Attempt to change memory protection failed.
Forward declaration.
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)