Name
cyg_mempool_fix_*(), cyg_mempool_var_*() — Additional Memory Pools
Synopsis
#include <cyg/kernel/kapi.h>
void cyg_mempool_fix_create
(
void* base
, cyg_int32 size
, cyg_int32 blocksize
, cyg_handle_t* handle
, cyg_mempool_fix* fix
)
;
void cyg_mempool_fix_delete
(
cyg_handle_t fixpool
)
;
void* cyg_mempool_fix_alloc
(
cyg_handle_t fixpool
)
;
void* cyg_mempool_fix_timed_alloc
(
cyg_handle_t fixpool
, cyg_tick_count_t abstime
)
;
void* cyg_mempool_fix_try_alloc
(
cyg_handle_t fixpool
)
;
void cyg_mempool_fix_free
(
cyg_handle_t fixpool
, void* ptr
)
;
cyg_bool_t cyg_mempool_fix_waiting
(
cyg_handle_t fixpool
)
;
void cyg_mempool_fix_get_info
(
cyg_handle_t fixpool
, cyg_mempool_info* info
)
;
void cyg_mempool_var_create
(
void* base
, cyg_int32 size
, cyg_handle_t* handle
, cyg_mempool_var* var
)
;
void cyg_mempool_var_delete
(
cyg_handle_t varpool
)
;
void* cyg_mempool_var_alloc
(
cyg_handle_t varpool
, size_t size
)
;
void* cyg_mempool_var_timed_alloc
(
cyg_handle_t varpool
, size_t size
, cyg_tick_count_t abstime
)
;
void* cyg_mempool_var_try_alloc
(
cyg_handle_t varpool
, size_t size
)
;
void cyg_mempool_var_free
(
cyg_handle_t varpool
, void* ptr
)
;
cyg_bool_t cyg_mempool_var_waiting
(
cyg_handle_t varpool
)
;
void cyg_mempool_var_get_info
(
cyg_handle_t varpool
, cyg_mempool_info* info
)
;
Description
The memory allocation package provides support for additional memory pools, to complement the system heap. These pools are not created automatically by the system, they have to be created by application code or by other packages. There are exported APIs for two types of pool: fixed and variable.
Allocating memory from a fixed memory pool is very fast and, more importantly, deterministic. However the size of each allocation is fixed at the time the pool is created. This is not a problem if the required allocations are all the same size, or nearly so, but otherwise the memory will be used inefficiently. The pool cannot become fragmented.
Variable memory pools provide essentially the same functionality as the system heap, so are rarely used. However on some targets not all free memory is assigned automatically to the system heap. For example there may be a small area of fast on-chip memory as well as the slower external memory. The system heap will only use the latter. A variable memory pool can be created for the former, allowing application code to dynamically allocate fast memory where appropriate.
If the eCos configuration includes the kernel then by default the
memory pool functions will be thread-safe. The pool functions do not
implement the malloc()
guard and free-fill debug
facilities, nor the debug data support.
Fixed Memory Pools
A fixed memory pool must be created explicitly, for example:
#define BLOCK_SIZE 1024 #define BLOCK_COUNT 64 static cyg_uint32 pool_memory[((BLOCK_COUNT * BLOCK_SIZE)+3) / 4]; static cyg_handle_t pool_handle; static cyg_mempool_fix pool_data; … cyg_mempool_fix_create( (void*) pool_memory, BLOCK_COUNT * BLOCK_SIZE, BLOCK_SIZE, &pool_handle, &pool_data );
This creates a pool of 63 1K blocks.
pool_memory
is normally allocated statically,
but could also be a pointer to a special area of memory such as
on-chip RAM, or it could even be dynamically allocated using
malloc()
. The pointer should be suitably aligned
for the target architecture, usually to either a 32 or a 64 bit
boundary. pool_handle
can be used for
subsequent pool operations. pool_data
is a
small data structure providing the space needed to administer the
pool.
The above pool only provides 63 blocks, not 64. The administration
overhead depends on the number of blocks so cannot all be allowed for
in the pool_data
structure. A small amount of
the pool memory is consumed as well, effectively using up all of the
first block. To eliminate this inefficiency:
#define BLOCK_SIZE 1024 #define BLOCK_COUNT 64 #define OVERHEAD (((BLOCK_COUNT + 31) / 32) * sizeof(cyg_uint32)) #define ACTUAL_SIZE ((BLOCK_SIZE * BLOCK_COUNT) + OVERHEAD) static cyg_uint32 pool_memory[(ACTUAL_SIZE + 3) / 4]; static cyg_handle_t pool_handle; static cyg_mempool_fix pool_data; … cyg_mempool_fix_create( pool_memory, ACTUAL_SIZE, BLOCK_SIZE, &pool_handle, &pool_data );
There are three functions for allocating memory.
cyg_mempool_fix_try_alloc()
is analogous to
malloc()
: it attempts to allocate a block from
the pool, returning a null pointer if all blocks are currently in use.
There is no need to specify the allocation size because all blocks are
the same size. The other two functions are only available in
configurations containing the eCos kernel.
cyg_mempool_fix_alloc()
will allocate a free
block if there is one available, otherwise the current thread will be
suspended until a block becomes available. A null pointer will only be
returned if the thread is woken up again via
cyg_thread_release()
.
cyg_mempool_fix_timed_alloc()
may also suspend
the current thread, but only for a number of clock ticks. If no block
becomes free before the specified time is reached then a null pointer
will be returned. The abstime
argument is an
absolute time, typically calculated by adding a
cyg_tick_count_t timeout to the result of
cyg_current_time()
. In other words the pool API
works in exactly the same way as kernel functions such as
cyg_semaphore_timed_wait()
.
cyg_mempool_fix_waiting()
can be used to check
whether any threads are currently suspended waiting for a free block.
A block can be released using
cyg_mempool_fix_free()
. If a pool is no longer
required it can be destroyed by a call to
cyg_mempool_fix_delete()
. Information about the
current state of a pool can be obtained with
cyg_mempool_fix_get_info()
, in the form of a
cyg_mempool_info structure:
typedef struct { cyg_int32 totalmem; cyg_int32 freemem; void* base; cyg_int32 size; cyg_int32 blocksize; cyg_int32 maxfree; // The largest free block } cyg_mempool_info;
Variable Memory Pools
The variable memory pool API is very similar to the fixed pool API. The key differences are:
-
cyg_mempool_var_create()
does not take a block size parameter since the pool supports allocations of any size. - There is no special need to worry about overheads when creating the pool. The overheads will be shared between the allocations so spread throughout the pool
-
The block size is no longer implicit, so the three allocation routines
need an explicit
size
argument. - Allocation operations are not deterministic and may take significantly longer than a fixed pool allocation. A variable pool is also vulnerable to memory fragmentation.
2024-03-18 | eCosPro Non-Commercial Public License |