...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::pool — A fast memory allocator that guarantees proper alignment of all allocated chunks.
// In header: <boost/pool/pool.hpp> template<typename UserAllocator> class pool : protected boost::simple_segregated_storage< UserAllocator::size_type > { public: // types typedef UserAllocator user_allocator; // User allocator. typedef UserAllocator::size_type size_type; // An unsigned integral type that can represent the size of the largest object to be allocated. typedef UserAllocator::difference_type difference_type; // A signed integral type that can represent the difference of any two pointers. // private member functions void * malloc_need_resize(); void * ordered_malloc_need_resize(); // protected member functions simple_segregated_storage< size_type > & store(); const simple_segregated_storage< size_type > & store() const; details::PODptr< size_type > find_POD(void *const) const; size_type alloc_size() const; size_type max_chunks() const; // protected static functions static bool is_from(void *const, char *const, const size_type); static void *& nextof(void *const); // public member functions explicit pool(const size_type, const size_type = 32, const size_type = 0); ~pool(); bool release_memory(); bool purge_memory(); size_type get_next_size() const; void set_next_size(const size_type); size_type get_max_size() const; void set_max_size(const size_type); size_type get_requested_size() const; void * malloc(); void * ordered_malloc(); void * ordered_malloc(size_type); void free(void *const); void ordered_free(void *const); void free(void *const, const size_type); void ordered_free(void *const, const size_type); bool is_from(void *const) const; };
Whenever an object of type pool needs memory from the system, it will request it from its UserAllocator template parameter. The amount requested is determined using a doubling algorithm; that is, each time more system memory is allocated, the amount of system memory requested is doubled.
Users may control the doubling algorithm by using the following extensions:
Users may pass an additional constructor parameter to pool. This parameter is of type size_type, and is the number of chunks to request from the system the first time that object needs to allocate system memory. The default is 32. This parameter may not be 0.
Users may also pass an optional third parameter to pool's constructor. This parameter is of type size_type, and sets a maximum size for allocated chunks. When this parameter takes the default value of 0, then there is no upper limit on chunk size.
Finally, if the doubling algorithm results in no memory being allocated, the pool will backtrack just once, halving the chunk size and trying again.
UserAllocator type - the method that the Pool will use to allocate memory from the system.
There are essentially two ways to use class pool: the client can call malloc() and free() to allocate and free single chunks of memory, this is the most efficient way to use a pool, but does not allow for the efficient allocation of arrays of chunks. Alternatively, the client may call ordered_malloc() and ordered_free(), in which case the free list is maintained in an ordered state, and efficient allocation of arrays of chunks are possible. However, this latter option can suffer from poor performance when large numbers of allocations are performed.
pool
private member functionsvoid * malloc_need_resize();
No memory in any of our storages; make a new storage, Allocates chunk in newly malloc aftert resize.
Returns: |
0 if out-of-memory. Called if malloc/ordered_malloc needs to resize the free list. |
Returns: |
pointer to chunk. |
void * ordered_malloc_need_resize();Called if malloc needs to resize the free list.
No memory in any of our storages; make a new storage,
Returns: |
pointer to new chunk. |
pool
protected member functionssimple_segregated_storage< size_type > & store();
Returns: |
pointer to store. |
const simple_segregated_storage< size_type > & store() const;
Returns: |
pointer to store. |
details::PODptr< size_type > find_POD(void *const chunk) const;finds which POD in the list 'chunk' was allocated from.
find which PODptr storage memory that this chunk is from.
Returns: |
the PODptr that holds this chunk. |
size_type alloc_size() const;
Calculated size of the memory chunks that will be allocated by this Pool.
Returns: |
allocated size. |
size_type max_chunks() const;
Calculated maximum number of memory chunks that can be allocated in a single call by this Pool.
pool
protected static functionsstatic bool is_from(void *const chunk, char *const i, const size_type sizeof_i);
Returns false if chunk was allocated from some other pool, or may be returned as the result of a future allocation from some other pool. Otherwise, the return value is meaningless.
Note that this function may not be used to reliably test random pointer values.
Parameters: |
|
||||||
Returns: |
true if chunk was allocated or may be returned. as the result of a future allocation. |
static void *& nextof(void *const ptr);
Returns: |
Pointer dereferenced. (Provided and used for the sake of code readability :) |
pool
public member functionsexplicit pool(const size_type nrequested_size, const size_type nnext_size = 32, const size_type nmax_size = 0);
Constructs a new empty Pool that can be used to allocate chunks of size RequestedSize.
Parameters: |
|
~pool();
Destructs the Pool, freeing its list of memory blocks.
bool release_memory();
pool must be ordered. Frees every memory block that doesn't have any allocated chunks.
Returns: |
true if at least one memory block was freed. |
bool purge_memory();
pool must be ordered. Frees every memory block.
This function invalidates any pointers previously returned by allocation functions of t.
Returns: |
true if at least one memory block was freed. |
size_type get_next_size() const;
Number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be 0.
Returns: |
next_size; |
void set_next_size(const size_type nnext_size);
Set number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be set to 0.
size_type get_max_size() const;
Returns: |
max_size. |
void set_max_size(const size_type nmax_size);
Set max_size.
size_type get_requested_size() const;
Returns: |
the requested size passed into the constructor. (This value will not change during the lifetime of a Pool object). |
void * malloc();
Allocates a chunk of memory. Searches in the list of memory blocks for a block that has a free chunk, and returns that free chunk if found. Otherwise, creates a new memory block, adds its free list to pool's free list,
Returns: |
a free chunk from that block. If a new memory block cannot be allocated, returns 0. Amortized O(1). |
void * ordered_malloc();
Same as malloc, only merges the free lists, to preserve order. Amortized O(1).
Returns: |
a free chunk from that block. If a new memory block cannot be allocated, returns 0. Amortized O(1). |
void * ordered_malloc(size_type n);
Gets address of a chunk n, allocating new memory if not already available.
Returns: |
Address of chunk n if allocated ok. |
Returns: |
0 if not enough memory for n chunks. |
void free(void *const chunk);
Same as malloc, only allocates enough contiguous chunks to cover n * requested_size bytes. Amortized O(n).
Deallocates a chunk of memory. Note that chunk may not be 0. O(1).
Chunk must have been previously returned by t.malloc() or t.ordered_malloc(). Assumes that chunk actually refers to a block of chunks spanning n * partition_sz bytes. deallocates each chunk in that block. Note that chunk may not be 0. O(n).
Returns: |
a free chunk from that block. If a new memory block cannot be allocated, returns 0. Amortized O(1). |
void ordered_free(void *const chunk);
Same as above, but is order-preserving.
Note that chunk may not be 0. O(N) with respect to the size of the free list. chunk must have been previously returned by t.malloc() or t.ordered_malloc().
void free(void *const chunks, const size_type n);
Assumes that chunk actually refers to a block of chunks.
chunk must have been previously returned by t.ordered_malloc(n) spanning n * partition_sz bytes. Deallocates each chunk in that block. Note that chunk may not be 0. O(n).
void ordered_free(void *const chunks, const size_type n);
Assumes that chunk actually refers to a block of chunks spanning n * partition_sz bytes; deallocates each chunk in that block.
Note that chunk may not be 0. Order-preserving. O(N + n) where N is the size of the free list. chunk must have been previously returned by t.malloc() or t.ordered_malloc().
bool is_from(void *const chunk) const;
Returns: |
Returns true if chunk was allocated from u or may be returned as the result of a future allocation from u. Returns false if chunk was allocated from some other pool or may be returned as the result of a future allocation from some other pool. Otherwise, the return value is meaningless. Note that this function may not be used to reliably test random pointer values. |