mbed allocator functions
C C++ CMake
Clone or download
Latest commit 35ab210 Mar 24, 2016

README.md

ualloc

ualloc implements a traits-based allocator, described below.

Memory in mbed OS

mbed OS provides memory allocation services that are based on a standard memory organization, described below. The memory allocation services provide for most use-cases in memory allocation, including heap allocation, pool allocation, and extendable pools.

Memory organization in mbed OS

In a conventional embedded system, there are four areas of memory: Code, Global Data, the heap, and the stack. Frequently, the heap and the stack are organized so that they occupy the same block of memory. In mbed OS, we add two additional areas of memory: uVisor memory and the never free heap. Memory is organized as below. Note that code generally lives in ROM, so it is not included in this diagram.

Cortex-M3/M4            Cortex-M0/M+        
Largest RAM address     Largest RAM address 
+-----------------+     +-----------------+ 
| Never Free Heap |     | Never Free Heap | 
|                 |     |                 | 
|      Heap       |     |      Heap       | 
+-----------------+     +-----------------+ 
|   Global Data   |     |   Global Data   | 
+-----------------+     +-----------------+ 
|      Stack      |     |      Stack      | 
+-----------------+     +-----------------+ 
|  uVisor Memory  |     Smallest RAM address
+-----------------+   
Smallest RAM address  

uVisor Memory

On Cortex-M3/M4, the uVisor reserves a small portion of memory at the beginning of RAM for itself and for secured features (boxes). The uVisor secures this area using the MPU. For more information on the uVisor, see our main site

Stack

The stack is placed at the bottom of the memory, and it grows downwards. This location is selected explicitly because it allows stack overflows to be easily caught. In a Cortex-M3/M4 system, where the uVisor is in use, the first access below the bottom of the stack will trigger a MemManage exception, handled by the uVisor. In a Cortex-M0/M0+ system, it will trigger a HardFault. This allows applications to recover from stack overflows, generally through a reset.

This organization does mean that a stack must be sized to match the application. Currently, this is a value set in the target, but a future version will expose stack configuration through yotta config.

Global Data

Global Data is the typical .bss and .data sections generated by the compiler. This section's size depends on the application and requires no configuration.

Heaps

There are two kinds of heap in mbed OS. The heap grows upwards from the bottom of the heap section, while the never free heap grows downwards from the top.

The standard heap

The standard heap is a typical dlmalloc heap, which grows upwards from the bottom of the heap section using the sbrk function provided by the core-util module.

The never free heap

The never free heap grows downwards from the end of memory. The never free heap is intended for use with data that need not be freed, such as memory pools. Memory is allocated from the never free heap using the reverse sbrk function (krbs) provided by the core-util module.

Memory Allocation in mbed OS

mbed OS provides several memory allocation services, including a traits allocator, a typical dlmalloc heap, a never free heap, a pool allocator and an extendable pool allocator. These facilities are built on top of two trivial, but lock-free, allocators: sbrk() and krbs() (a reverse sbrk).

Usage Notes

In general, you should use mbed_ualloc() where malloc-type allocation is necessary. Standard library functions, such as malloc(), realloc(), and calloc can also be used, but they are not as flexible as mbed_ualloc(). You should avoid using sbrk() and krbs() where possible; these are low-level functions, intended for use by other memory allocators.

Where memory is allocated in interrupt context, or similarly sized memory is used frequently, it can be advantageous to use PoolAllocator or ExtendablePoolAllocator. malloc(), realloc(), and calloc should not be called from an interrupt context. mbed_ualloc() should only be called from an interrupt context with the UALLOC_TRAITS_NEVER_FREE trait set.

ualloc traits allocator

In mbed OS, all memory allocation is done through a traits allocator, ualloc. ualloc provides features that support both the dlmalloc heap and the never free heap. Currently, only two traits are supported in ualloc: UALLOC_TRAITS_NEVER_FREE, which allocates from the never-free region, and UALLOC_TRAITS_ZERO_FILL, which zeros the allocated space prior to returning it, much like calloc. ualloc hooks several of the standard library functions:

  • malloc
  • calloc
  • realloc
  • free

This is to ensure that all allocations are done via ualloc, which in turn ensures that all compilers with all libc's will produce the same memory behavior. Using ualloc as a the channel for all memory allocations also provides a common point for memory allocation analysis. By analyzing calls to ualloc functions, it is possible to monitor all memory allocation behavior.

For allocations with the UALLOC_TRAITS_NEVER_FREE trait, ualloc calls krbs() directly. Without the never-free trait, ualloc calls dlmalloc functions.

The standard heap

The standard heap is managed by dlmalloc. For standard heap operations, ualloc forwards operations to dlmalloc. dlmalloc, in turn, uses sbrk() to obtain more memory.

The pool allocator

mbed OS provides a pool allocator in the core-util module, called PoolAllocator. This allocator divides its block of memory into 4-byte aligned regions of fixed size. The pool allocator is lock-free and very fast, so it is suitable for use in interrupt context. PoolAllocator can run out of memory, however, so for some operations, ExtendablePoolAllocator is more useful.

The extendable pool allocator

mbed OS also provides an extendable pool allocator in the core-util module, called ExtendablePoolAllocator. It is built on top of PoolAllocator, with the sole difference that, when ExtendablePoolAllocator runs out of pool elements to allocate, it can request more from the never free heap, using ualloc(), with the UALLOC_TRAITS_NEVER_FREE flag set.

sbrk

sbrk is a trivial allocator implemented in the core-util module. It supports linear allocation and deallocation. It is completely lock-free.

krbs

krbs is effectively the reverse of sbrk(), allocating memory from the end of a section, rather than the beginning. The one exception in behavior is that krbs() does not support deallocation.