fragpool
20170302
Variable-sized packet memory management for embedded applications
|
Header providing interface for fragpool functions. More...
#include <stdint.h>
Go to the source code of this file.
Data Structures | |
struct | fp_fragment_t |
struct | FP_POOL_STRUCT_COMMON_ |
struct | fp_pool_t |
Macros | |
#define | FP_VERSION 20170302 |
#define | FP_MAX_FRAGMENT_SIZE INT16_MAX |
#define | FP_EINVAL 1 |
#define | FP_POOL_STRUCT_COMMON |
Typedefs | |
typedef uint16_t | fp_size_t |
typedef int16_t | fp_ssize_t |
typedef struct fp_fragment_t * | fp_fragment_t |
typedef struct fp_pool_t * | fp_pool_t |
Functions | |
void | fp_reset (fp_pool_t pool) |
uint8_t * | fp_request (fp_pool_t pool, fp_size_t min_size, fp_size_t max_size, uint8_t **fragment_endp) |
uint8_t * | fp_resize (fp_pool_t pool, uint8_t *bp, fp_size_t new_size, uint8_t **fragment_endp) |
uint8_t * | fp_reallocate (fp_pool_t pool, uint8_t *bp, fp_size_t min_size, fp_size_t max_size, uint8_t **fragment_endp) |
int | fp_release (fp_pool_t pool, const uint8_t *bp) |
int | fp_validate (const fp_pool_t pool) |
Header providing interface for fragpool functions.
See Fragpool: Variable-sized packet memory management for embedded applications.
#define FP_EINVAL 1 |
The (positive) value of the error code returned when a fragpool function is invoked with unacceptable parameters.
#define FP_MAX_FRAGMENT_SIZE INT16_MAX |
The maximum size of a fragment. This is intentionally a signed value.
#define FP_POOL_STRUCT_COMMON |
Prefix common to all pool structures.
For documentation on these fields see the pseudo-structure FP_POOL_STRUCT_COMMON_.
Although struct fp_pool_t has a flexible array member that makes it easy to dynamically allocate a pool structure, the whole point of fragpool is its use in systems that don't do dynamic allocation. In that situation, each static pool definition needs its own structure that defines the fragment array to the correct size. An example of how to accomplish this while still using the generic type for reference to the pool is:
static uint8_t pool_data[POOL_SIZE]; static union { struct { FP_POOL_STRUCT_COMMON; struct fp_fragment_t fragment[POOL_FRAGMENTS]; } fixed; struct fp_pool_t generic; } pool_union = { .generic = { .pool_start = pool_data, .pool_end = pool_data + sizeof(pool_data), .pool_alignment = sizeof(int), .fragment_count = POOL_FRAGMENTS, } }; fp_pool_t const pool = &pool_union.generic;
#define FP_VERSION 20170302 |
A integral monotonically increasing version number
typedef struct fp_fragment_t * fp_fragment_t |
Bookkeeping for a fragment within the pool.
The fragment state is allocated if its memory has been made available to a caller; available if its memory has been returned to the pool; inactive if the pool partitions do not include this fragment.
Bookkeeping for a fragment pool.
typedef uint16_t fp_size_t |
Type used to represent a fragment size in API calls.
typedef int16_t fp_ssize_t |
A signed fragment size, for internal use where the sign carries non-length significance.
uint8_t* fp_reallocate | ( | fp_pool_t | pool, |
uint8_t * | bp, | ||
fp_size_t | min_size, | ||
fp_size_t | max_size, | ||
uint8_t ** | fragment_endp | ||
) |
Attempt to resize a fragment allowing moves.
This operation will place the fragment in the best available location, moving it if necessary to do so. The expectation is this operation is equivalent to saving the current fragment contents, releasing the fragment, requesting a new fragment with the specified characteristics, and initializing it with the old fragment contents, but without requiring external storage for what's currently in the fragment.
If no satisfactory fragment can be found, the function returns a null pointer, but the existing fragment is not affected.
pool | the pool from which bp was allocated |
bp | the start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate(). |
min_size | the minimum acceptable size for a new fragment. Up to this many octets from the existing fragment are copied if the new fragment begins at a different location. The current fragment may be smaller or larger than this size. For the purposes of determining a new location the value is increased to satisfy the pool alignment, but the provided value is used when preserving the buffer contents. |
max_size | the maximum size desired for the fragment, in bytes. This is increased if necessary to satisfy the pool alignment requirements. Use FP_MAX_FRAGMENT_SIZE to get the largest available fragment. |
fragment_endp | where to store the end of the fragment. The stored value is unchanged if the call returns NULL . |
int fp_release | ( | fp_pool_t | pool, |
const uint8_t * | bp | ||
) |
Release a block of memory to the pool.
pool | the pool from which bp was allocated |
bp | the start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate(). |
bp
is invalid. uint8_t* fp_request | ( | fp_pool_t | pool, |
fp_size_t | min_size, | ||
fp_size_t | max_size, | ||
uint8_t ** | fragment_endp | ||
) |
Obtain a block of memory from the pool.
A block of memory of at least min_size
octets is allocated from the pool and returned to the caller. The value pointed to by fragment_endp
is updated to reflect the first byte past the end of the allocated region. The "best" available fragment is selected taking into account the required min_size
and the desired max_size
. If the requested maximum size is smaller than the selected fragment and there are slots available, the remainder is split off as a new available fragment.
pool | the pool from which memory is obtained |
min_size | the minimum size acceptable fragment, in bytes. This is increased if necessary to satisfy the pool alignment requirements. |
max_size | the maximum size desired for the fragment, in bytes. This is increased if necessary to satisfy the pool alignment requirements. Use FP_MAX_FRAGMENT_SIZE to get the largest available fragment. |
fragment_endp | where to store the end of the fragment |
void fp_reset | ( | fp_pool_t | pool | ) |
Reset the pool.
All memory is assigned to a single fragment which is marked unallocated.
pool | the pool to be validated |
Attempt to resize a fragment in-place.
This operation will release trailing bytes to the pool or attempt to extend the fragment if the following fragment is available.
If the new size is smaller, the excess will be returned to the pool if possible.
If the new size is larger and the following fragment is available, the fragment will be extended to be no longer than new_size. It may be extended even if the requested new size cannot be satisfied.
The resize will not move any data. The caller is responsible for checking *fragment_endp
to determine the effect of the resize.
pool | the pool from which bp was allocated |
bp | the start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate(). |
new_size | the new desired size for the fragment, in bytes. This is increased if necessary to satisfy the pool alignment requirements. Use FP_MAX_FRAGMENT_SIZE to get the largest available fragment. |
fragment_endp | where to store the end of the fragment. This must not be NULL . |
bp
if the resize succeeded, or a null pointer if an invalid fragment or pool address was provided. In either case, the new_size
octets beginning at bp
are unchanged. *fragment_endp
is updated to reflect the actual end of the fragment after the resize completes.new_size <= (*fragment_endp - bp)
to hold on successful completion. Equality should not be expected. int fp_validate | ( | const fp_pool_t | pool | ) |
Verify the integrity of the pool.
pool | the pool to be validated |