POOL_ALLOC(3)

NAME
pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool_destroy, pool_boundary - Allocate and free memory in managed allocation pools.

SYNOPSIS
#include pool_alloc.h struct alloc_pool *pool_create(size_t size, size_t quantum, void (*bomb)(char *), int flags); void pool_destroy(struct alloc_pool *pool); void *pool_alloc(struct alloc_pool *pool, size_t size, char *msg); void pool_free(struct alloc_pool *pool, size_t size, void *addr); void pool_free_old(struct alloc_pool *pool, void *addr); void *pool_talloc(struct alloc_pool *pool, type), int count, char *msg); void pool_tfree(struct alloc_pool *pool, type, int count, void *addr); void pool_boundary(struct alloc_pool *pool, sise_t size);

DESCRIPTION

The pool allocation routines use malloc() for underlying memory management. What allocation pools do is cause memory within a given pool to be allocated in large contiguous blocks (called extents) that will be reusable when freed. Unlike malloc(), the allocations are not managed individually. Instead, each extent tracks the total free memory within the extent. Each extent can either be used to allocate memory or to manage the freeing of memory within that extent. When an extent has less free memory than a given allocation request, the current extent ceases to be used for allocation. See also the pool_boundary() function.

This form of memory management is suited to large numbers of small related allocations that are held for a while and then freed as a group. Because the underlying allocations are done in large contiguous extents, when an extent is freed, it can release a large enough contiguous block of memory to allow the memory to be returned to the OS for use by whatever program needs it. You can allocate from one or more memory pools and/or malloc() all at the same time without interfering with how pools work.

pool_create() Creates an allocation pool for subsequent calls to the pool allocation functions. When an extent is created for allocations it will be size bytes. Allocations from the pool have their sizes rounded up to a multiple of quantum bytes in length. Specifying 0 for quantum will produce a quantum that should meet maximal alignment on most platforms. Unless POOL_NO_QALIGN is set in the flags, allocations will be aligned to addresses that are a multiple of quantum. A NULL may be specified for the bomb function pointer if it is not needed. (See the pool_alloc() function for how it is used.) If POOL_CLEAR is set in the flags, all allocations from the pool will be initialized to zeros. If either POOL_PREPEND or POOL_INTERN is specified in the flags, each extent's data structure will be allocated at the start of the size-length buffer (rather than as a separate, non-pool allocation), with the former extending the size to hold the structure, and the latter subtracting the structure's length from the indicated size.

pool_destroy() destroys an allocation pool and frees all its associated memory.

pool_alloc() allocates size bytes from the specified pool. If size is 0, quantum bytes will be allocated. If the pool has been created without POOL_NO_QALIGN, every chunk of memory that is returned will be suitably aligned. You can use this with the default quantum size to ensure that all memory can store a variable of any type. If the requested memory cannot be allocated, the bomb() function will be called with msg as its sole argument (if the function was defined at the time the pool was created), and then a NULL address is returned (assuming that the bomb function didn't exit).

pool_free() frees size bytes pointed to by an addr that was previously allocated in the specified pool. If size is 0, quantum bytes will be freed. The memory freed within an extent will not be reusable until all of the memory in that extent has been freed with one exception: the most recent pool allocation may be freed back into the pool prior to making any further allocations. If enough free calls are made to indicate that an extent has no remaining allocated objects (as computed by the total freed size for an extent), its memory will be completely freed back to the system. If addr is NULL, no memory will be freed, but subsequent allocations will come from a new extent.

pool_free_old() takes a boundary addr value that was returned by pool_boundary() and frees up any extents in the pool that have data allocated from that point backward in time. NOTE: you must NOT mix calls to both pool_free and pool_free_old on the same pool!

pool_boundary() asks for a boundary value that can be sent to pool_free_old() at a later time to free up all memory allocated prior to a particular moment in time. If the extent that holds the boundary point has allocations from after the boundary point, it will not be freed until a future pool_free_old() call encompasses the entirety of the extent's data. If len is non-zero, the call will also check if the active extent has at least that much free memory available in it, and if not, it will mark the extent as inactive, forcing a new extent to be used for future allocations. (You can specify -1 for len if you want to force a new extent to start.)

pool_talloc() is a macro that takes a type and a count instead of a size. It casts the return value to the correct pointer type.

pool_tfree is a macro that calls pool_free on memory that was allocated by pool_talloc().

RETURN VALUE
pool_create() returns a pointer to struct alloc_pool.

pool_alloc() and pool_talloc() return pointers to the allocated memory, or NULL if the request fails. The return type of pool_alloc() will normally require casting to the desired type but pool_talloc() will returns a pointer of the requested type.

pool_boundary() returns a pointer that should only be used in a call to pool_free_old().

pool_free(), pool_free_old(), pool_tfree() and pool_destroy() return no value.

SEE ALSO
malloc(3)

AUTHOR
pool_alloc was created by J.W. Schultz of Pegasystems Technologies.

BUGS AND ISSUES