ATLAS Offline Software
Loading...
Searching...
No Matches
SG::ArenaHeapAllocator Class Reference

Heap-based allocator. More...

#include <ArenaHeapAllocator.h>

Inheritance diagram for SG::ArenaHeapAllocator:
Collaboration diagram for SG::ArenaHeapAllocator:

Classes

struct  initParams
 Helper to initialize a parameters structure. More...

Public Types

typedef void iterator
typedef void const_iterator
typedef char * pointer
 Type for pointers to elements.
typedef const char * const_pointer
 And a const version of the pointer.
typedef void func_t(pointer)
 Type of functions for constructor, etc.

Public Member Functions

 ArenaHeapAllocator (const Params &params)
 Constructor.
virtual ~ArenaHeapAllocator ()
 Destructor.
 ArenaHeapAllocator (const ArenaHeapAllocator &)=delete
 Don't allow copy construction or assignment.
ArenaHeapAllocatoroperator= (const ArenaHeapAllocator &)=delete
 ArenaHeapAllocator (ArenaHeapAllocator &&other)
 Move constructor.
ArenaHeapAllocatoroperator= (ArenaHeapAllocator &&other)
 Move assignment.
void swap (ArenaHeapAllocator &other)
 Swap.
pointer allocate ()
 Allocate a new element.
void free (pointer p)
 Free an element.
virtual void reset () override
 Free all allocated elements.
virtual void erase () override final
 Free all allocated elements and release memory back to the system.
void swap (ArenaBlockAllocatorBase &other)
 Swap.
virtual void reserve (size_t size) override
 Set the total number of elements cached by the allocator.
virtual Stats stats () const override
 Return the statistics block for this allocator.
virtual const std::string & name () const override
 Return the name of this allocator.
const Paramsparams () const
 Return this Allocator's parameters.
void protect ()
 Write-protect the memory managed by this allocator.
void unprotect ()
 Write-enable the memory managed by this allocator.
virtual void report (std::ostream &os) const
 Generate a report on the memory usage of this allocator.

Static Public Member Functions

template<class T>
static func_tmakeConstructor (const std::false_type &)
 Make a constructor function pointer for a non-trivial constructor.
template<class T>
static func_tmakeConstructor (const std::true_type &)
 Make a constructor function pointer for a trivial constructor.
template<class T>
static func_tmakeDestructor (const std::false_type &)
 Make a constructor function pointer for a non-trivial destructor.
template<class T>
static func_tmakeDestructor (const std::true_type &)
 Make a constructor function pointer for a trivial destructor.
template<class T>
static func_tmakeClear (const std::false_type &)
 Make a function pointer for a clear function.
template<class T>
static func_tmakeClear (const std::true_type &)
 Make a dummy clear function pointer.

Protected Member Functions

ArenaBlockgetBlock ()
 Return an empty block, either newly-allocated or from the free list.
void eraseUnprotected ()
 Free all allocated elements and release memory back to the system.

Protected Attributes

Params m_params
 The parameters for this allocator.
ArenaBlockm_blocks
 The list of blocks currently in use.
ArenaBlockm_freeblocks
 The list of free blocks.
ArenaAllocatorBase::Stats m_stats
 The statistics structure.
bool m_protected
 Flag whether the arena has been protected.

Private Member Functions

void slowClear ()
 Call clear() for all allocated elements.
pointer refill ()
 Add more free elements to the pool, and allocate a new element.
pointerlink (pointer p) const
 Return a reference to the link for an element.

Static Private Member Functions

template<typename T>
static void construct_fcn (pointer p)
 Call T's default constructor on the object at p.
template<typename T>
static void destroy_fcn (pointer p)
 Call T's destructor on the object at p.
template<typename T>
static void clear_fcn (pointer p)
 Call T::clear on the object at p.

Private Attributes

pointer m_freeptr
 Pointer to the next free element.

Detailed Description

Heap-based allocator.

See Arena.h for an overview of the arena-based memory allocators.

This is a block-based memory allocator, with heap-like behavior. This allows freeing individual elements, but we don't implement resetTo or an iterator.

There are some extra costs though.

  • We need an additional pointer (‘link’) for each free element.

    By default, this is done by increasing the element size by a pointer, since we don't know whether there is data in the element itself that must be preserved across free/allocate. However, if you know that part of the element may be safely while it is free, then the allocator can be configured to use that as the link instead.

  • When reset() is called, we need to call clear() on all allocated elements (if it is defined). If canReclear is set, then we just call clear() on all elements in allocated blocks on reset(), regardless of whether or not the individual elements are allocated or not. Otherwise, we make two passes over the elements, first to build a list of those that are allocated and second to actually call clear().

    An intermediate strategy, not currently implemented, could be used if the link does not overlap the element: set the link to a magic value when an element is allocated.

Definition at line 62 of file ArenaHeapAllocator.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 190 of file ArenaHeapAllocator.h.

◆ const_pointer

typedef const char* SG::ArenaAllocatorBase::const_pointer
inherited

And a const version of the pointer.

Definition at line 140 of file ArenaAllocatorBase.h.

◆ func_t

typedef void SG::ArenaAllocatorBase::func_t(pointer)
inherited

Type of functions for constructor, etc.

Definition at line 143 of file ArenaAllocatorBase.h.

◆ iterator

Definition at line 189 of file ArenaHeapAllocator.h.

◆ pointer

typedef char* SG::ArenaAllocatorBase::pointer
inherited

Type for pointers to elements.

Definition at line 137 of file ArenaAllocatorBase.h.

Constructor & Destructor Documentation

◆ ArenaHeapAllocator() [1/3]

SG::ArenaHeapAllocator::ArenaHeapAllocator ( const Params & params)

Constructor.

Parameters
paramsThe parameters structure for this allocator. See ArenaAllocatorBase.h for the contents.

Definition at line 28 of file ArenaHeapAllocator.cxx.

30 m_freeptr (nullptr)
31{
32 // Consistency check.
33 assert (params.linkOffset + sizeof (pointer) <= params.eltSize);
34}
char * pointer
Type for pointers to elements.
const Params & params() const
Return this Allocator's parameters.
ArenaBlockAllocatorBase(const Params &params)
Constructor.
pointer m_freeptr
Pointer to the next free element.

◆ ~ArenaHeapAllocator()

SG::ArenaHeapAllocator::~ArenaHeapAllocator ( )
virtual

Destructor.

This will free all the Allocator's storage.

Definition at line 40 of file ArenaHeapAllocator.cxx.

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}
void unprotect()
Write-enable the memory managed by this allocator.
void eraseUnprotected()
Free all allocated elements and release memory back to the system.
bool m_protected
Flag whether the arena has been protected.

◆ ArenaHeapAllocator() [2/3]

SG::ArenaHeapAllocator::ArenaHeapAllocator ( const ArenaHeapAllocator & )
delete

Don't allow copy construction or assignment.

◆ ArenaHeapAllocator() [3/3]

SG::ArenaHeapAllocator::ArenaHeapAllocator ( ArenaHeapAllocator && other)

Move constructor.

Definition at line 58 of file ArenaHeapAllocator.cxx.

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}

Member Function Documentation

◆ allocate()

pointer SG::ArenaHeapAllocator::allocate ( )

Allocate a new element.

The fast path of this will be completely inlined.

◆ clear_fcn()

template<typename T>
void SG::ArenaAllocatorBase::clear_fcn ( pointer p)
staticprivateinherited

Call T::clear on the object at p.

Parameters
pThe object on which to run the clear.

◆ construct_fcn()

template<typename T>
void SG::ArenaAllocatorBase::construct_fcn ( pointer p)
staticprivateinherited

Call T's default constructor on the object at p.

Parameters
pThe object on which to run the constructor.

◆ destroy_fcn()

template<typename T>
void SG::ArenaAllocatorBase::destroy_fcn ( pointer p)
staticprivateinherited

Call T's destructor on the object at p.

Parameters
pThe object on which to run the destructor.

◆ erase()

void SG::ArenaHeapAllocator::erase ( )
finaloverridevirtual

Free all allocated elements and release memory back to the system.

All elements allocated are freed, and all allocated blocks of memory are released back to the system. destructor should be called on them if it was provided (preceded by clear if provided and mustClear was set).

Reimplemented from SG::ArenaBlockAllocatorBase.

Definition at line 139 of file ArenaHeapAllocator.cxx.

140{
142 m_freeptr = nullptr;
143}
virtual void erase() override
Free all allocated elements and release memory back to the system.

◆ eraseUnprotected()

void SG::ArenaBlockAllocatorBase::eraseUnprotected ( )
protectedinherited

Free all allocated elements and release memory back to the system.

Assumes that the blocks are already unprotected.

Definition at line 186 of file ArenaBlockAllocatorBase.cxx.

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}
virtual void reset()=0
Free all allocated elements.
ArenaAllocatorBase::Stats m_stats
The statistics structure.
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.
static void destroyList(ArenaBlock *p, func_t *dtor)
Destroy all blocks in a list.

◆ free()

void SG::ArenaHeapAllocator::free ( pointer p)

Free an element.

Parameters
pThe element to be freed.

clear() will be called on the element at this point, if it has been defined.

◆ getBlock()

ArenaBlock * SG::ArenaBlockAllocatorBase::getBlock ( )
protectedinherited

Return an empty block, either newly-allocated or from the free list.

Update statistics appropriately.

Definition at line 245 of file ArenaBlockAllocatorBase.cxx.

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}
static ArenaBlock * newBlock(size_t n, size_t elt_size, func_t *ctor)
Create a new block.

◆ link()

pointer & SG::ArenaHeapAllocator::link ( pointer p) const
private

Return a reference to the link for an element.

Parameters
pThe element.

◆ makeClear() [1/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeClear ( const std::false_type & )
staticinherited

Make a function pointer for a clear function.

◆ makeClear() [2/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeClear ( const std::true_type & )
staticinherited

Make a dummy clear function pointer.

◆ makeConstructor() [1/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeConstructor ( const std::false_type & )
staticinherited

Make a constructor function pointer for a non-trivial constructor.

◆ makeConstructor() [2/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeConstructor ( const std::true_type & )
staticinherited

Make a constructor function pointer for a trivial constructor.

◆ makeDestructor() [1/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeDestructor ( const std::false_type & )
staticinherited

Make a constructor function pointer for a non-trivial destructor.

◆ makeDestructor() [2/2]

template<class T>
func_t * SG::ArenaAllocatorBase::makeDestructor ( const std::true_type & )
staticinherited

Make a constructor function pointer for a trivial destructor.

◆ name()

const std::string & SG::ArenaBlockAllocatorBase::name ( ) const
overridevirtualinherited

Return the name of this allocator.

Implements SG::ArenaAllocatorBase.

Definition at line 225 of file ArenaBlockAllocatorBase.cxx.

226{
227 return m_params.name;
228}

◆ operator=() [1/2]

ArenaHeapAllocator & SG::ArenaHeapAllocator::operator= ( ArenaHeapAllocator && other)

Move assignment.

Definition at line 73 of file ArenaHeapAllocator.cxx.

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}
ArenaBlockAllocatorBase & operator=(const ArenaBlockAllocatorBase &)=delete

◆ operator=() [2/2]

ArenaHeapAllocator & SG::ArenaHeapAllocator::operator= ( const ArenaHeapAllocator & )
delete

◆ params()

const ArenaAllocatorBase::Params & SG::ArenaBlockAllocatorBase::params ( ) const
inherited

Return this Allocator's parameters.

Return this allocator's parameters.

Definition at line 235 of file ArenaBlockAllocatorBase.cxx.

236{
237 return m_params;
238}

◆ protect()

void SG::ArenaBlockAllocatorBase::protect ( )
inherited

Write-protect the memory managed by this allocator.

Adjust protection on the memory managed by this allocator to disallow writes.

Definition at line 281 of file ArenaBlockAllocatorBase.cxx.

282{
284 m_protected = true;
285}
static void protectList(ArenaBlock *p)
Write-protect all blocks in a list.

◆ refill()

ArenaHeapAllocator::pointer SG::ArenaHeapAllocator::refill ( )
private

Add more free elements to the pool, and allocate a new element.

Definition at line 149 of file ArenaHeapAllocator.cxx.

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}
static Double_t sz
ArenaBlock * getBlock()
Return an empty block, either newly-allocated or from the free list.
pointer & link(pointer p) const
Return a reference to the link for an element.

◆ report()

void SG::ArenaAllocatorBase::report ( std::ostream & os) const
virtualinherited

Generate a report on the memory usage of this allocator.

Parameters
osStream to which the report should be written.

Definition at line 130 of file ArenaAllocatorBase.cxx.

131{
132 os << " " << stats() << " " << name() << std::endl;
133}
virtual const std::string & name() const =0
Return the name of this allocator.
virtual Stats stats() const =0
Return the statistics block for this allocator.

◆ reserve()

void SG::ArenaBlockAllocatorBase::reserve ( size_t size)
overridevirtualinherited

Set the total number of elements cached by the allocator.

Parameters
sizeThe desired pool size.

This allows changing the number of elements that are currently free but cached. Any allocated elements are not affected by this call.

If size is greater than the total number of elements currently cached, then more will be allocated. This will preferably done with a single block, but that is not guaranteed; in addition, the allocator may allocate more elements than is requested.

If size is smaller than the total number of elements currently cached, as many blocks as possible will be released back to the system. It may not be possible to release the number of elements requested; this should be implemented on a best-effort basis.

Implements SG::ArenaAllocatorBase.

Definition at line 120 of file ArenaBlockAllocatorBase.cxx.

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.
149 ArenaBlock* p = m_freeblocks;
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}
static void destroy(ArenaBlock *p, func_t *dtor)
Destroy a block.

◆ reset()

void SG::ArenaHeapAllocator::reset ( )
overridevirtual

Free all allocated elements.

All elements allocated are returned to the free state. clear should be called on them if it was provided. The elements may continue to be cached internally, without returning to the system.

Implements SG::ArenaAllocatorBase.

Definition at line 105 of file ArenaHeapAllocator.cxx.

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}
static void appendList(ArenaBlock **headp, ArenaBlock *tail)
Concatenate two lists of blocks.
static void applyList(ArenaBlock *p, func_t *func, size_t n)
Call a function on elements in a list of blocks.
void slowClear()
Call clear() for all allocated elements.

◆ slowClear()

void SG::ArenaHeapAllocator::slowClear ( )
private

Call clear() for all allocated elements.

Definition at line 174 of file ArenaHeapAllocator.cxx.

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}
#define pi
void func_t(pointer)
Type of functions for constructor, etc.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ stats()

ArenaAllocatorBase::Stats SG::ArenaBlockAllocatorBase::stats ( ) const
overridevirtualinherited

Return the statistics block for this allocator.

Implements SG::ArenaAllocatorBase.

Definition at line 207 of file ArenaBlockAllocatorBase.cxx.

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}
virtual Stats stats() const override
Return the statistics block for this allocator.
static size_t overhead()
Return the per-block memory overhead, in bytes.
Statistics for an allocator.

◆ swap() [1/2]

void SG::ArenaBlockAllocatorBase::swap ( ArenaBlockAllocatorBase & other)
inherited

Swap.

Definition at line 91 of file ArenaBlockAllocatorBase.cxx.

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}
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)

◆ swap() [2/2]

void SG::ArenaHeapAllocator::swap ( ArenaHeapAllocator & other)

Swap.

Definition at line 88 of file ArenaHeapAllocator.cxx.

89{
90 if (this != &other) {
92 std::swap (m_freeptr, other.m_freeptr);
93 }
94}
void swap(ArenaBlockAllocatorBase &other)
Swap.

◆ unprotect()

void SG::ArenaBlockAllocatorBase::unprotect ( )
inherited

Write-enable the memory managed by this allocator.

Adjust protection on the memory managed by this allocator to allow writes.

Definition at line 294 of file ArenaBlockAllocatorBase.cxx.

295{
296 if (m_protected) {
298 m_protected = false;
299 }
300}
static void unprotectList(ArenaBlock *p)
Write-enable all blocks in a list.

Member Data Documentation

◆ m_blocks

ArenaBlock* SG::ArenaBlockAllocatorBase::m_blocks
protectedinherited

The list of blocks currently in use.

Definition at line 161 of file ArenaBlockAllocatorBase.h.

◆ m_freeblocks

ArenaBlock* SG::ArenaBlockAllocatorBase::m_freeblocks
protectedinherited

The list of free blocks.

Definition at line 164 of file ArenaBlockAllocatorBase.h.

◆ m_freeptr

pointer SG::ArenaHeapAllocator::m_freeptr
private

Pointer to the next free element.

Definition at line 213 of file ArenaHeapAllocator.h.

◆ m_params

Params SG::ArenaBlockAllocatorBase::m_params
protectedinherited

The parameters for this allocator.

Definition at line 158 of file ArenaBlockAllocatorBase.h.

◆ m_protected

bool SG::ArenaBlockAllocatorBase::m_protected
protectedinherited

Flag whether the arena has been protected.

Definition at line 170 of file ArenaBlockAllocatorBase.h.

◆ m_stats

ArenaAllocatorBase::Stats SG::ArenaBlockAllocatorBase::m_stats
protectedinherited

The statistics structure.

Definition at line 167 of file ArenaBlockAllocatorBase.h.


The documentation for this class was generated from the following files: