Table of Contents

OSLIB Memory Allocators

Both RT and NIL kernels are fully static, no memory is allocated or freed at runtime, all objects positions are defined at link time. While dynamic allocation is not required OSLIB supports 3 different allocators in case the application requires reliable and thread-aware memory management.

Global Settings

CH_CFG_USE_MEMCORE This switch enables the core allocator module, this module is required by all the other memory management modules.
CH_CFG_MEMCORE_SIZE Size of the memory block to use as system heap. If set to zero then the whole available RAM is used as system heap.
CH_CFG_USE_HEAP This switch enables the heap allocator module.
CH_CFG_USE_MEMPOOLS This switch enables the memory pool allocator module.

Allocator Types

The 4 kinds of allocators are designed to work together:

The Core Allocator

This allocator is able to efficiently return memory blocks from a memory area called the system heap. This allocator features:

The System Heap

The System Heap is a contiguous RAM memory area where the Core Allocator operates, it is organized as follow:

 The System Heap

The parameter CH_CFG_MEMCORE_SIZE specifies how much RAM has to be used for the system heap, the system area is created as a plain array and takes space from the compiler BSS section.

If CH_CFG_MEMCORE_SIZE is set to zero then linker is expected to export two symbols:

Notes

Conventionally the bottom-to-top allocation is used as an _sbrk() implementation in order to support the C runtime. The top-to-bottom allocation is used by ChibiOS application and/or to feed blocks to the two other OSLIB allocators (pool allocator, heap allocator).

This is done in order to let the C runtime allocate contiguous blocks, several C library implementations make this assumption.

Alignments and Offsets

When allocating a block it is possible to specify the following parameters:

The returned block looks as follow:

Memory block

Note that the total allocated size is the sum of Size, Offset and lost space caused by alignment enforcement.

Core Allocator API

chCoreAllocFromBase() Allocates a memory block bottom-to-top.
chCoreAllocFromBaseI() Allocates a memory block bottom-to-top (I-Class variant).
chCoreAllocFromTop() Allocates a memory block top-to-bottom.
chCoreAllocFromTopI() Allocates a memory block top-to-bottom (I-Class variant).
chCoreGetStatusX() Returns the remaining space in the system heap.

The Pool Allocator

This allocator is able to efficiently return memory blocks from a pool of fixed-size objects. This allocator features:

Diagram

A pool is a linked list of objects of fixed size, allocating an object means removing the first object in the list, freeing an objects means inserting it on top of the list, both operations are fixed-time.

 Pool

Note that a freed object is not guaranteed to keep its content intact when it is allocated again because it is overwritten with the linked list pointer. The provider is a function implementing the same prototype of the Core Allocator “alloc” functions. The Core Allocator itself can be, and usually is, used as provider.

Pool Allocator API

memory_pool_t Type of a memory pool object.
MEMORYPOOL_DECL() Memory Pool static initializer.
chPoolObjectInit() Initializes a memory_pool_t object with default alignment restrictions.
chPoolObjectInitAligned() Initializes a memory_pool_t object with specific alignment restrictions.
chPoolLoadArray() Loads an array of objects into a pool.
chPoolAlloc() Allocates an object from the pool.
chPoolAllocI() Allocates an object from the pool (I-Class variant).
chPoolFree() Returns an object into the pool.
chPoolFreeI() Returns an object into the pool (I-Class variant).
chPoolAdd() Synonym of chPoolFree().
chPoolAddI() Synonym of chPoolFreeI().

The Guarded Pool Allocator

This allocator is able to efficiently return memory blocks from a pool of fixed-size objects. It is a variation of the Pool Allocator where the allocation operations are protected with a semaphore. This allocator features:

Diagram

A guarded pool is a linked list of objects of fixed size, allocating an object means removing the first object in the list, freeing an objects means inserting it on top of the list, only freeing and object is a fixed-time operation.

The semaphore counter represents the number of objects available in the pool, a thread trying to allocate an object on an empty pool would wait on the semaphore. When an object becomes available, the first waiting thread, if any, is resumed and gets the object.

 Guarded Pool

Note that a freed object is not guaranteed to keep its content intact when it is allocated again because it is overwritten with the linked list pointer.

Guarded Pool Allocator API

guarded_memory_pool_t Type of a guarded memory pool object.
GUARDEDMEMORYPOOL_DECL() Guarded Memory Pool static initializer.
chGuardedPoolObjectInit() Initializes a guarded_memory_pool_t object with default alignment restrictions.
chGuardedPoolObjectInitAligned() Initializes a guarded_memory_pool_t object with specific alignment restrictions.
chGuardedPoolLoadArray() Loads an array of objects into a guarded pool.
chGuardedPoolAlloc() Allocates an object from the guarded pool.
chGuardedPoolAllocI() Allocates an object from the pool (I-Class variant).
chGuardedPoolAllocTimeout() Allocates an object from the guarded pool with timeout.
chGuardedPoolAllocTimeoutS() Allocates an object from the guarded pool with timeout (S-Class variant).
chGuardedPoolFree() Returns an object into the guarded pool.
chGuardedPoolFreeI() Returns an object into the guarded pool (I-Class variant).
chGuardedPoolFreeS() Returns an object into the guarded pool (S-Class variant).
chGuardedPoolAdd() Synonym of chGuardedPoolFree().
chGuardedPoolAddI() Synonym of chGuardedPoolFreeI().
chGuardedPoolAddS() Synonym of chGuardedPoolFreeS().

The Heap Allocator

This allocator implements the traditional malloc() and free() paradigm but with some peculiarities:

Heap Allocator API

memory_heap_t Type of a memory heap object.
chHeapObjectInit() Initializes an heap object of type memory_heap_t. .
chHeapAlloc() Allocates a memory block.
chHeapAllocAligned() Allocates an aligned memory block.
chHeapFree Returns a memory block to its heap.
chHeapStatus() Returns status information about an heap like remaining space and fragmentation.
chHeapGetSize() Returns the size of an allocated memory block.

Allocators Comparison

All the allocators can be used together but some are best suited in specific scenarios, this is a brief comparison:

Allocator Can Free Constant Time Variable Size From ISR Creates Fragments Thread Safe
Core Allocator no yes yes yes - yes
Pool Allocator yes yes no yes no yes
Guarded Pool Allocator yes no no yes1 no yes
Heap Allocator yes no yes no yes yes
C Library Allocator yes no yes no yes no2
  1. Without waiting.
  2. Depends on library implementation and integration with the RTOS.

The selection of the appropriate allocator depends on requirements of your application, there is not an universal best solution.