simple_segregated_storage.hpp provides a template class simple_segregated_storage that controls access to a free list of memory chunks. Please note that this is a very simple class, with preconditions on almost all its functions. It is intended to be the fastest and smallest possible quick memory allocator — e.g., something to use in embedded systems. This class delegates many difficult preconditions to the user (i.e., alignment issues). For more general usage, see the other pool interfaces.
template <typename SizeType = std::size_t>
class simple_segregated_storage
{
private:
simple_segregated_storage(const simple_segregated_storage &);
void operator=(const simple_segregated_storage &);
public:
typedef SizeType size_type;
simple_segregated_storage();
~simple_segregated_storage();
static void * segregate(void * block,
size_type nsz, size_type npartition_sz,
void * end = 0);
void add_block(void * block,
size_type nsz, size_type npartition_sz);
void add_ordered_block(void * block,
size_type nsz, size_type npartition_sz);
bool empty() const;
void * malloc();
void free(void * chunk);
void ordered_free(void * chunk);
void * malloc_n(size_type n, size_type partition_sz);
void free_n(void * chunks, size_type n,
size_type partition_sz);
void ordered_free_n(void * chunks, size_type n,
size_type partition_sz);
};
An object of type simple_segregated_storage<SizeType> is empty if its free list is empty. If it is not empty, then it is ordered if its free list is ordered. A free list is ordered if repeated calls to malloc() will result in a constantly-increasing sequence of values, as determined by std::less<void *>. A member function is order-preserving if the free list maintains its order orientation (that is, an ordered free list is still ordered after the member function call).
| Symbol | Meaning |
|---|---|
| Store | simple_segregated_storage<SizeType> |
| t | value of type Store |
| u | value of type const Store |
| block, chunk, end | values of type void * |
| partition_sz, sz, n | values of type Store::size_type |
| Parameter | Default | Requirements |
|---|---|---|
| SizeType | std::size_t | An unsigned integral type |
| Symbol | Type |
|---|---|
| size_type | SizeType |
| Expression | Return Type | Post-Condition | Notes |
|---|---|---|---|
| Store() | not used | empty() | Constructs a new Store |
| (&t)->~Store() | not used | Destructs the Store | |
| u.empty() | bool | Returns true if u is empty. Order-preserving. |
| Expression | Return Type | Pre-Condition | Post-Condition | Semantic Equivalence | Notes |
|---|---|---|---|---|---|
| Store::segregate(block, sz, partition_sz, end) | void * | partition_sz >= sizeof(void *) partition_sz = sizeof(void *) * i, for some integer i sz >= partition_sz block is properly aligned for an array of objects of size partition_sz block is properly aligned for an array of void * |
Interleaves a free list through the memory block specified by block of size sz bytes, partitioning it into as many partition_sz-sized chunks as possible. The last chunk is set to point to end, and a pointer to the first chunck is returned (this is always equal to block). This interleaved free list is ordered. O(sz). | ||
| Store::segregate(block, sz, partition_sz) | void * | Same as above | Store::segregate(block, sz, partition_sz, 0) | ||
| t.add_block(block, sz, partition_sz) | void | Same as above | !t.empty() | Segregates the memory block specified by block of size sz bytes into partition_sz-sized chunks, and adds that free list to its own. If t was empty before this call, then it is ordered after this call. O(sz). | |
| t.add_ordered_block(block, sz, partition_sz) | void | Same as above | !t.empty() | Segregates the memory block specified by block of size sz bytes into partition_sz-sized chunks, and merges that free list into its own. Order-preserving. O(sz). |
| Expression | Return Type | Pre-Condition | Post-Condition | Semantic Equivalence | Notes |
|---|---|---|---|---|---|
| t.malloc() | void * | !t.empty() | Takes the first available chunk from the free list and returns it. Order-preserving. O(1). | ||
| t.free(chunk) | void | chunk was previously returned from a call to t.malloc() | !t.empty() | Places chunk back on the free list. Note that chunk may not be 0. O(1). | |
| t.ordered_free(chunk) | void | Same as above | !t.empty() | Places chunk back on the free list. Note that chunk may not be 0. Order-preserving. O(N) with respect to the size of the free list. | |
| t.malloc_n(n, partition_sz) | void * | Attempts to find a contiguous sequence of n partition_sz-sized chunks. If found, removes them all from the free list and returns a pointer to the first. If not found, returns 0. It is strongly recommended (but not required) that the free list be ordered, as this algorithm will fail to find a contiguous sequence unless it is contiguous in the free list as well. Order-preserving. O(N) with respect to the size of the free list. | |||
| t.free_n(chunk, n, partition_sz) | void | chunk was previously returned from a call to t.malloc_n(n, partition_sz) | !t.empty() | t.add_block(chunk, n * partition_sz, partition_sz) | Assumes that chunk actually refers to a block of chunks spanning n * partition_sz bytes; segregates and adds in that block. Note that chunk may not be 0. O(n). |
| t.ordered_free_n(chunk, n, partition_sz) | void | same as above | same as above | t.add_ordered_block(chunk, n * partition_sz, partition_sz) | Same as above, except it merges in the free list. Order-preserving. O(N + n) where N is the size of the free list. |
Revised 05 December, 2006
Copyright © 2000, 2001 Stephen Cleary (scleary AT jerviswebb DOT com)
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)