JASSv2
Classes | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions | List of all members
JASS::allocator_pool Class Reference

Simple block-allocator that internally allocates a large chunk then allocates smaller blocks from this larger block. More...

#include <allocator_pool.h>

Inheritance diagram for JASS::allocator_pool:
Inheritance graph
[legend]
Collaboration diagram for JASS::allocator_pool:
Collaboration graph
[legend]

Classes

class  chunk
 Details of an individual large-allocation unit. More...
 

Public Member Functions

 allocator_pool (size_t block_size_for_allocation=default_allocation_size)
 Constructor. More...
 
virtual ~allocator_pool ()
 Destructor.
 
virtual bool operator== (const allocator &with)
 Compare for equality two objects of this class type. More...
 
virtual bool operator!= (const allocator &with)
 Compare for inequlity two objects of this class type. More...
 
virtual void * malloc (size_t bytes, size_t alignment=alignment_boundary)
 Allocate a small chunk of memory from the internal block and return a pointer to the caller. More...
 
virtual void rewind (void)
 Throw away (without calling delete) all objects allocated in the memory space of this object. More...
 
- Public Member Functions inherited from JASS::allocator
 allocator ()
 Constructor.
 
virtual ~allocator ()
 Destructor.
 
size_t capacity (void) const
 Return the amount of memory that this object has allocated to it. More...
 
size_t size (void) const
 Return the number of bytes of memory this object has handed back to callers. More...
 

Static Public Member Functions

static void unittest_thread (dynamic_array< uint8_t *> &answer, allocator_pool &memory, uint8_t bytes)
 Unit test this class - thread manager. More...
 
static void unittest (void)
 Unit test this class.
 
- Static Public Member Functions inherited from JASS::allocator
static size_t realign (const void *address, size_t boundary)
 Compute the number of extra bytes of memory necessary for an allocation to start on an aligned boundary. More...
 
static size_t realign (uintptr_t current_pointer, size_t boundary)
 Compute the number of extra bytes of memory necessary for an allocation to start on an aligned boundary. More...
 

Protected Member Functions

void * alloc (size_t size) const
 Allocate more memory from the C++ free-store. More...
 
void dealloc (void *buffer) const
 Hand back to the C++ free store (or Operating system) a chunk of memory that has previously been allocated with allocator_pool::alloc(). More...
 
chunkadd_chunk (size_t bytes)
 Get memory from the C++ free store (or the Operating System) and add it to the linked list of large-allocations. More...
 

Protected Attributes

size_t block_size
 The size (in bytes) of the large-allocations this object will make.
 
std::atomic< chunk * > current_chunk
 Pointer to the top of the chunk list (of large allocations).
 
- Protected Attributes inherited from JASS::allocator
std::atomic< size_t > used
 The number of bytes this object has passed back to the caller.
 
std::atomic< size_t > allocated
 The number of bytes this object has allocated.
 

Static Protected Attributes

static const size_t default_allocation_size = 1024 * 1024 * 128
 Allocations from the C++ free-store are this size.
 
- Static Protected Attributes inherited from JASS::allocator
static constexpr size_t alignment_boundary = 1
 Elsewhere don't bother with alignment (align on byte boundaries)
 

Private Member Functions

 allocator_pool (allocator_pool &)=delete
 
allocator_pooloperator= (const allocator_pool &)=delete
 

Detailed Description

Simple block-allocator that internally allocates a large chunk then allocates smaller blocks from this larger block.

This is a simple block allocator that internally allocated a large single block from the C++ free-store (or operating system) and then allows calls to allocate small blocks from that one block. These small blocks cannot be individually deallocated, but rather are all deallocated all at once when rewind() is called. C++ allocators can easily be defined that allocate from a single object of this type, but that is left for other classes to manage (for example, class allocator_cpp).

If the large memory block "runs out" then a second (and subsequent) block are allocated from the C++ free-store and they are chained together. If the caller askes for a single piece of memory larger then that default_allocation_size then this class will allocate a chunk of the required size and return that to the caller. Note that there is wastage at the end of each chunk as they cannot be guaranteed to lay squentially in memory.

By default allocations by this class are not aligned to any particular boundary. That is, if 1 byte is allocated then the next memory allocation is likely to be exactly one byte further on. So allocation of a uint8_t followed by the allocation of a uint32_t is likely to result in the uint32_t being at an odd-numbered memory location. Call malloc() with an alignment value to allocate an aligned piece of memory. On ARM, all memory allocations are word-aligned (sizeof(void *) by default because unaligned reads usually cause a fault.

The use of new and delete in C++ (and malloc and free in C) is expensive as a substantial amount of work is necessary in order to maintain the heap. This class reduces that cost - it exists for efficiency reasons alone.

This allocator is thread safe. A single allocator can be called from multiple threads concurrently and they will each return a valid pointer to a piece of memory that is not overlapping with any pointer returned from any other call and is of the requested size.

Constructor & Destructor Documentation

◆ allocator_pool()

JASS::allocator_pool::allocator_pool ( size_t  block_size_for_allocation = default_allocation_size)

Constructor.

Parameters
block_size_for_allocation[in] This size of the large-chunk allocation from the C++ free store or the Operating System.

Member Function Documentation

◆ add_chunk()

allocator_pool::chunk * JASS::allocator_pool::add_chunk ( size_t  bytes)
protected

Get memory from the C++ free store (or the Operating System) and add it to the linked list of large-allocations.

This is a maintenance method whose function is to allocate large chunks of memory and to maintain the liked list of these large chunks. As an allocator this object is allocating memory for the caller, so it may as well manage its own list. The bytes parameter to this method is an indicator of the minimum amount of memory the caller requires, this object will allocate at leat that amount of space plus any space necessary for housekeeping.

Parameters
bytes[in] Allocate space so that it is possible to return an allocation is this parameter is size.
Returns
A pointer to a chunk containig at least this amount of free space.

◆ alloc()

void* JASS::allocator_pool::alloc ( size_t  size) const
inlineprotected

Allocate more memory from the C++ free-store.

Parameters
size[in] The size (in bytes) of the requested block.
Returns
A pointer to a block of memory of size size, or NULL on failure.

◆ dealloc()

void JASS::allocator_pool::dealloc ( void *  buffer) const
inlineprotected

Hand back to the C++ free store (or Operating system) a chunk of memory that has previously been allocated with allocator_pool::alloc().

Parameters
buffer[in] A pointer previously returned by allocator_pool::alloc()

◆ malloc()

void * JASS::allocator_pool::malloc ( size_t  bytes,
size_t  alignment = alignment_boundary 
)
virtual

Allocate a small chunk of memory from the internal block and return a pointer to the caller.

Parameters
bytes[in] The size of the chunk of memory.
alignment[in] If a word-aligned piece of memory is needed then this is the word-size (e.g. sizeof(void*))
Returns
A pointer to a block of memory of size bytes, or NULL on failure.

Implements JASS::allocator.

◆ operator!=()

virtual bool JASS::allocator_pool::operator!= ( const allocator with)
inlinevirtual

Compare for inequlity two objects of this class type.

Any two unused allocator_pool objects are equal until one or the other is first used.

Parameters
with[in] The object to compare to.
Returns
True if this != that, else false.

Implements JASS::allocator.

◆ operator==()

virtual bool JASS::allocator_pool::operator== ( const allocator with)
inlinevirtual

Compare for equality two objects of this class type.

Any two unused allocator_pool objects are equal until one or the other is first used.

Parameters
with[in] The object to compare to.
Returns
True if this == that, else false.

Implements JASS::allocator.

◆ rewind()

void JASS::allocator_pool::rewind ( void  )
virtual

Throw away (without calling delete) all objects allocated in the memory space of this object.

This method rolls-back the memory that has been allocated by handing it all back to the C++ free store (or operating system). delete is not called for any objects allocated in this space, the memory is simply re-claimed.

Implements JASS::allocator.

◆ unittest_thread()

void JASS::allocator_pool::unittest_thread ( dynamic_array< uint8_t *> &  answer,
allocator_pool memory,
uint8_t  bytes 
)
static

Unit test this class - thread manager.

Parameters
answer[out] A pointer to the allocated memory.
memory[in] The object to thread-test.
bytes[in] The size of this thread's allocation.

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