Lumiera  0.pre.03
»edit your freedom«
AllocationCluster Class Reference

#include "lib/allocation-cluster.hpp"

Description

A pile of objects sharing common allocation and lifecycle.

AllocationCluster owns a heterogeneous collection of objects of various types. Typically, allocation happens during a short time span when building a new segment, and objects are used together until the segment is discarded. The primary leverage is to bulk-allocate memory, and to avoid invoking destructors (and thus to access a lot of cache-cold memory pages on clean-up). A Stdlib compliant #Allocator is provided for use with STL containers. The actual allocation uses heap memory in extents of hard-wired size, maintained by the accompanying StorageManager.

Warning
use #createDisposable whenever possible, but be sure to understand the ramifications of not invoking an object's destructor.

Definition at line 87 of file allocation-cluster.hpp.

Public Member Functions

 AllocationCluster ()
 Prepare a new clustered allocation to be expanded by extents of size EXTENT_SIZ, yet discarded all at once when the dtor is called. More...
 
 ~AllocationCluster () noexcept
 The shutdown of an AllocationCluster walks all extents and invokes all registered deleter functions and then discards the complete storage. More...
 
bool canAdjust (void *loc, size_t oldSiz, size_t newSiz) const
 
template<class TY , typename... ARGS>
TY & create (ARGS &&...)
 
template<class TY , typename... ARGS>
TY & create (ARGS &&...args)
 Factory function: place a new instance into this AllocationCluster; the object will be properly destroyed when the cluster goes out of scope. More...
 
template<class TY , typename... ARGS>
TY & createDisposable (ARGS &&...)
 
template<class TY , typename... ARGS>
TY & createDisposable (ARGS &&...args)
 Factory function: place a new instance into this AllocationCluster, but without invoking its destructor on clean-up (for performance reasons).
 
void doAdjust (void *loc, size_t oldSiz, size_t newSiz)
 Adjust the size of the latest raw memory allocation dynamically. More...
 
template<typename X >
Allocator< X > getAllocator ()
 
size_t numBytes () const
 
size_t numExtents () const
 

Static Public Member Functions

static size_t constexpr max_size ()
 Maximum individual allocation size that can be handled. More...
 

Static Public Attributes

static size_t constexpr EXTENT_SIZ = 256
 hard wired size of storage extents
 

Classes

struct  AllocationWithDestructor
 
struct  Allocator
 
class  Destructor
 
struct  Storage
 maintaining the Allocation More...
 
class  StorageManager
 An overlay view for the AllocationCluster to add functionality for adding / clearing extents and registering optional deleter functions. More...
 

Friends

class test::AllocationCluster_test
 

Private Member Functions

void __enforce_limits (size_t, size_t)
 Allocation cluster uses a comparatively small tile size for its extents, which turns out to be a frequently encountered limitation in practice. More...
 
template<typename X >
X * allot (size_t cnt=1)
 
void * allotMemory (size_t bytes, size_t alignment)
 portion out the requested amount of memory, possibly claiming a new pool block.
 
void expandStorage (size_t)
 Expand the alloted storage pool by a block, suitable to accommodate at least the indicated request. More...
 
void registerDestructor (Destructor &)
 
- Private Member Functions inherited from MoveOnly
 MoveOnly (MoveOnly &&)=default
 
 MoveOnly (MoveOnly const &)=delete
 
MoveOnlyoperator= (MoveOnly &&)=delete
 
MoveOnlyoperator= (MoveOnly const &)=delete
 

Private Attributes

Storage storage_
 

Constructor & Destructor Documentation

◆ AllocationCluster()

Prepare a new clustered allocation to be expanded by extents of size EXTENT_SIZ, yet discarded all at once when the dtor is called.

The constructor does not allocate anything immediately.

Definition at line 207 of file allocation-cluster.cpp.

◆ ~AllocationCluster()

~AllocationCluster ( )
noexcept

The shutdown of an AllocationCluster walks all extents and invokes all registered deleter functions and then discards the complete storage.

Note
it is possible to allocate objects as disposable — meaning that no destructors will be enrolled and called for such objects.

Definition at line 220 of file allocation-cluster.cpp.

References ERROR_LOG_AND_IGNORE.

Member Function Documentation

◆ max_size()

size_t constexpr max_size ( )
static

Maximum individual allocation size that can be handled.

Remarks
AllocationCluser expands its storage buffer in steps of fixed sized tiles or extents. Doing so can be beneficial when clusters are frequently created and thrown away (which is the intended usage pattern). However, using such extents is inherently wasteful, and thus the size must be rather tightly limited.

Definition at line 234 of file allocation-cluster.hpp.

Referenced by SeveralBuilder_test::check_CustomAllocator(), AllocationCluster::expandStorage(), and AllocationCluster::numBytes().

+ Here is the caller graph for this function:

◆ numBytes()

size_t numBytes ( ) const
Warning
whenever there are more than one extent, the returned byte count is guessed only (upper bound), since actually allocated size is not tracked to save some overhead.

Definition at line 296 of file allocation-cluster.cpp.

References AllocationCluster::max_size().

Referenced by SeveralBuilder_test::check_CustomAllocator(), AllocationCluster_test::dynamicAdjustment(), LinkedElements_test::verify_customAllocator(), and AllocationCluster_test::verifyInternals().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ doAdjust()

void doAdjust ( void *  loc,
size_t  oldSiz,
size_t  newSiz 
)
inline

Adjust the size of the latest raw memory allocation dynamically.

Parameters
locan allocation provided by this AllocationCluster
oldSizthe size requested for the allocation loc
newSizdesired new size for this allocation
Remarks
since AllocationCluster must be used in a single threaded environment, the invoking code can sometimes arrange to adapt the latest allocation to a dynamically changing situation, like e.g. populating a container with a previously unknown number of elements. Obviously, the overall allocation must stay within the confines of the current extent; it is thus mandatory to check the ability beforehand.

Definition at line 283 of file allocation-cluster.hpp.

◆ expandStorage()

void expandStorage ( size_t  allocRequest)
private

Expand the alloted storage pool by a block, suitable to accommodate at least the indicated request.

Remarks
Storage blocks are organised as linked list, allowing to de-allocate all blocks together.

Definition at line 241 of file allocation-cluster.cpp.

References AllocationCluster::max_size().

+ Here is the call graph for this function:

◆ __enforce_limits()

void __enforce_limits ( size_t  allocSiz,
size_t  align 
)
private

Allocation cluster uses a comparatively small tile size for its extents, which turns out to be a frequently encountered limitation in practice.

This was deemed acceptable, due to its orientation towards performance.

Exceptions
err::Fatalwhen a desired allocation can not be accommodated

Definition at line 263 of file allocation-cluster.cpp.

◆ create()

TY& create ( ARGS &&...  args)
inline

Factory function: place a new instance into this AllocationCluster; the object will be properly destroyed when the cluster goes out of scope.

Note
whenever possible, the #createDisposable variant should be preferred

Definition at line 258 of file allocation-cluster.hpp.

+ Inheritance diagram for AllocationCluster:
+ Collaboration diagram for AllocationCluster:

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