fragpool  20170302
Variable-sized packet memory management for embedded applications
Data Structures | Macros | Typedefs | Functions
fragpool.h File Reference

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_tfp_fragment_t
 
typedef struct fp_pool_tfp_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)
 

Detailed Description

Header providing interface for fragpool functions.

See Fragpool: Variable-sized packet memory management for embedded applications.

Homepage
http://github.com/pabigot/fragpool

Macro Definition Documentation

§ FP_EINVAL

#define FP_EINVAL   1

The (positive) value of the error code returned when a fragpool function is invoked with unacceptable parameters.

§ FP_MAX_FRAGMENT_SIZE

#define FP_MAX_FRAGMENT_SIZE   INT16_MAX

The maximum size of a fragment. This is intentionally a signed value.

§ FP_POOL_STRUCT_COMMON

#define FP_POOL_STRUCT_COMMON
Value:
uint8_t* pool_start; \
uint8_t* pool_end; \
uint8_t pool_alignment; \
uint8_t fragment_count

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;

§ FP_VERSION

#define FP_VERSION   20170302

A integral monotonically increasing version number

Typedef Documentation

§ fp_fragment_t

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.

Warning
The only reason you get to see the internals is because this is C and we need to statically allocate pools in user code. You don't get to inspect or mutate the fields of this structure, so any descriptive comments are irrelevant to you.

§ fp_pool_t

typedef struct fp_pool_t * fp_pool_t

Bookkeeping for a fragment pool.

Warning
The only reason you get to see the internals is because this is C and we need to statically allocate pools in user code. You don't get to inspect or mutate the fields of this structure, so any descriptive comments are irrelevant to you.

§ fp_size_t

typedef uint16_t fp_size_t

Type used to represent a fragment size in API calls.

Note
Due to sign tricks used internally, the effective maximum size is fp_ssize_t.

§ fp_ssize_t

typedef int16_t fp_ssize_t

A signed fragment size, for internal use where the sign carries non-length significance.

Function Documentation

§ fp_reallocate()

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.

Parameters
poolthe pool from which bp was allocated
bpthe start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate().
min_sizethe 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_sizethe 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_endpwhere to store the end of the fragment. The stored value is unchanged if the call returns NULL.
Returns
a pointer to the start of the returned region, or a null pointer if the allocation cannot be satisfied.

§ fp_release()

int fp_release ( fp_pool_t  pool,
const uint8_t *  bp 
)

Release a block of memory to the pool.

Parameters
poolthe pool from which bp was allocated
bpthe start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate().
Returns
zero if the block is released, or an error code if bp is invalid.

§ fp_request()

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.

Parameters
poolthe pool from which memory is obtained
min_sizethe minimum size acceptable fragment, in bytes. This is increased if necessary to satisfy the pool alignment requirements.
max_sizethe 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_endpwhere to store the end of the fragment
Returns
a pointer to the start of the returned region, or a null pointer if the allocation cannot be satisfied.

§ fp_reset()

void fp_reset ( fp_pool_t  pool)

Reset the pool.

All memory is assigned to a single fragment which is marked unallocated.

Parameters
poolthe pool to be validated

§ fp_resize()

uint8_t* fp_resize ( fp_pool_t  pool,
uint8_t *  bp,
fp_size_t  new_size,
uint8_t **  fragment_endp 
)

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.

Parameters
poolthe pool from which bp was allocated
bpthe start of an allocated block returned by fp_request(), fp_resize(), or fp_reallocate().
new_sizethe 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_endpwhere to store the end of the fragment. This must not be NULL.
Returns
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.
Note
Expect new_size <= (*fragment_endp - bp) to hold on successful completion. Equality should not be expected.

§ fp_validate()

int fp_validate ( const fp_pool_t  pool)

Verify the integrity of the pool.

Parameters
poolthe pool to be validated
Returns
zero if the pool is valid, or an internal error code if an integrity test fails.