ROSE
0.11.96.11
|
Small object allocation from memory pools.
This class manages allocation and deallocation of small objects from pools. This allocator has pools available for a variety of small object sizes, or falls back to the global new
and delete
operators for larger objects. Each pool contains zero or more large chunks of contiguous memory from which storage for the small objects are obtained. The following template parameters control the number and sizes of pools:
smallestCell
is the size in bytes of the smallest cells. An "cell" is a small unit of storage and may be larger than what is requested when allocating memory for an object. The value must be at least as large as a pointer. Memory requests that are smaller than a cell lead to internal fragmentation. sizeDelta
is the difference in size in bytes between the cells of two neighboring pools. The value must be positive. When looking for a pool that will satisfy an allocation request, the allocator chooses the pool having the smallest cells that are at least as large as the request. nPools
is the total number of pools, each having a different size of cells. If pools are numbered zero through n then the size of cells is chunkSize
is the size of each chunk in bytes. Chunks are the unit of allocation requested from the runtime. All chunks in the allocator are the same size regardless of the cell size, and this may lead to external fragmentation—extra space at the end of a chunk that is not large enough for a complete cell. The chunk size should be large in relation to the largest cell size (that's the whole point of pool allocation). Sync
is the syncrhonization mechanism and can be either Sawyer::SingleThreadedTag or Sawyer::MultiThreadedTag. A single-threaded pool requires synchronization in the caller in order to prevent concurrent calls to the allocator, but a multi-threaded pool performs the synchronization internally. Single-threaded pools are somewhat faster.The SynchronizedPoolAllocator and UnsynchronizedPoolAllocator typedefs provide reasonable template arguments.
When a pool allocator is copied, only its settings are copied, not the pools. Since containers typically copy their constructor-provided allocators, each container will have its own pools even if one provides the same pool to all the constructors. See ProxyAllocator for a way to avoid this, and to allow different containers to share the same allocator.
Deleting a pool allocator deletes all its pools, which deletes all the chunks, which deallocates memory that might be in use by objects allocated from this allocator. In other words, don't destroy the allocator unless you're willing that the memory for any objects in use will suddenly be freed without even calling the destructors for those objects.
Definition at line 60 of file PoolAllocator.h.
#include <PoolAllocator.h>
Public Types | |
enum | { SMALLEST_CELL = smallestCell } |
enum | { SIZE_DELTA = sizeDelta } |
enum | { N_POOLS = nPools } |
enum | { CHUNK_SIZE = chunkSize } |
enum | { N_FREE_LISTS = 32 } |
Public Member Functions | |
PoolAllocatorBase () | |
Default constructor. | |
PoolAllocatorBase (const PoolAllocatorBase &) | |
Copy constructor. More... | |
virtual | ~PoolAllocatorBase () |
Destructor. More... | |
void * | allocate (size_t size) |
Allocate one object of specified size. More... | |
void | reserve (size_t objectSize, size_t nObjects) |
Reserve a certain number of objects in the pool. More... | |
std::pair< size_t, size_t > | nAllocated () const |
Number of objects allocated and reserved. More... | |
void | deallocate (void *addr, size_t size) |
Deallocate an object of specified size. More... | |
void | vacuum () |
Delete unused chunks. More... | |
void | showInfo (std::ostream &out) const |
Print pool allocation information. More... | |
Static Public Member Functions | |
static size_t | poolNumber (size_t size) |
Pool number for a request size. More... | |
static size_t | cellSize (size_t poolNumber) |
Size of each cell for a given pool. More... | |
static size_t | nCells (size_t poolNumber) |
Number of cells per chunk. More... | |
|
inline |
Copy constructor.
Copying an allocator does not copy its pools, but rather creates a new allocator that is empty but has the same settings as the source allocator.
Definition at line 367 of file PoolAllocator.h.
|
inlinevirtual |
Destructor.
Destroying a pool allocator destroys all its pools, which means that any objects that use storage managed by this pool will have their storage deleted.
Definition at line 380 of file PoolAllocator.h.
|
inlinestatic |
Pool number for a request size.
The return value is a pool number assuming that an infinite number of pools is available. In practice, if the return value is greater than or equal to the nPools
template argument then allocation is handled by the global "new" operator rather than this allocator.
Definition at line 393 of file PoolAllocator.h.
Referenced by Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::allocate(), Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::cellSize(), Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::deallocate(), Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::nCells(), and Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::reserve().
|
inlinestatic |
Size of each cell for a given pool.
Returns the number of bytes per cell for the given pool.
Definition at line 400 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::poolNumber().
Referenced by Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::nCells(), and Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::showInfo().
|
inlinestatic |
Number of cells per chunk.
Returns the number of cells contained in each chunk of the specified pool.
Definition at line 407 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::cellSize(), and Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::poolNumber().
|
inline |
Allocate one object of specified size.
Allocates one cell from an allocation pool, using the pool with the smallest-sized cells that are large enough to satisfy the request. If the request is larger than that available from any pool then the global "new" operator is used.
The requested size must be positive.
Thread safety: This method is thread safe.
Definition at line 422 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::poolNumber().
|
inline |
Reserve a certain number of objects in the pool.
The pool for the specified object size has its storage increased if necessary so that it is prepared to allocate the indicated additional number of objects (beyond the number of objects already allocated). I.e., upon return from this call, the free lists will contain in total, at least the specified number of objects. The reserved objects are divided equally between all free lists, and since allocations randomly select free lists from which to satisfy requests, one should reserve slightly more than what will be needed. Reserving storage is entirely optional.
Definition at line 435 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::poolNumber().
|
inline |
Number of objects allocated and reserved.
Returns a pair containing the number of objects currently allocated in the pool, and the number of objects that the pool can hold (including those that are allocated) before the pool must request more memory from the system.
Thread safety: This method is thread-safe. Of course, for a heavily contested pool the results are probably outdated by time they're returned to the caller
Definition at line 450 of file PoolAllocator.h.
|
inline |
Deallocate an object of specified size.
The addr
must be an object address that was previously returned by the allocate method and which hasn't been deallocated in the interim. The size
must be the same as the argument passed to the allocate call that returned this address.
Thread safety: This method is thread-safe.
Definition at line 469 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::poolNumber().
|
inline |
Delete unused chunks.
A pool allocator is optimized for the utmost performance when allocating and deallocating small objects, and therefore does minimal bookkeeping and does not free chunks. This method traverses the free lists to discover which chunks have no cells in use, removes those cells from the free list, and frees the chunk.
Thread safety: This method is thread-safe.
Definition at line 488 of file PoolAllocator.h.
|
inline |
Print pool allocation information.
Prints some interesting information about each chunk of each pool. The output will be multiple lines.
Thread safety: This method is thread-safe.
Definition at line 498 of file PoolAllocator.h.
References Sawyer::PoolAllocatorBase< smallestCell, sizeDelta, nPools, chunkSize, Sync >::cellSize().