.. _memory_slabs_v2: Memory slabs ############ A :dfn:`memory slab` is a kernel object that allows memory blocks to be dynamically allocated from a designated memory region. All memory blocks in a memory slab have a single fixed size, allowing them to be allocated and released efficiently and avoiding memory fragmentation concerns. .. contents:: :local: :depth: 2 Concepts ******** Any number of memory slabs can be defined. Each memory slab is referenced by its memory address. A memory slab has the following key properties: * The **block size** of each block, measured in bytes. It must be at least 4 bytes long. * The **number of blocks** available for allocation. It must be greater than zero. * A **buffer** that provides the memory for the memory slab's blocks. It must be at least "block size" times "number of blocks" bytes long. A thread that needs to use a memory block simply allocates it from a memory slab. When the thread finishes with a memory block, it must release the block back to the memory slab so the block can be reused. If all the blocks are currently in use, a thread can optionally wait for one to become available. Any number of threads may wait on an empty memory slab simultaneously; when a memory block becomes available, it is given to the highest-priority thread that has waited the longest. Unlike a heap, more than one memory slab can be defined, if needed. This allows for a memory slab with smaller blocks and others with larger-sized blocks. Alternatively, a memory pool object may be used. Internal Operation ================== A memory slab's buffer is an array of fixed-size blocks, with no wasted space between the blocks. The memory slab keeps track of unallocated blocks using a linked list; the first 4 bytes of each unused block provide the necessary linkage. Implementation ************** Defining a Memory Slab ====================== A memory slab is defined using a variable of type :c:type:`struct k_mem_slab`. It must then be initialized by calling :cpp:func:`k_mem_slab_init()`. The following code defines and initializes a memory slab that has 6 blocks of 400 bytes each and is aligned to a 4-byte boundary.. .. code-block:: c struct k_mem_slab my_slab; char __aligned(4) my_slab_buffer[6 * 400]; k_mem_slab_init(&my_slab, my_slab_buffer, 400, 6); Alternatively, a memory slab can be defined and initialized at compile time by calling :c:macro:`K_MEM_SLAB_DEFINE()`. The following code has the same effect as the code segment above. Observe that the macro defines both the memory slab and its buffer. .. code-block:: c K_MEM_SLAB_DEFINE(my_slab, 400, 6, 4); Allocating a Memory Block ========================= A memory block is allocated by calling :cpp:func:`k_mem_slab_alloc()`. The following code builds on the example above, and waits up to 100 milliseconds for a memory block to become available, then fills it with zeroes. A warning is printed if a suitable block is not obtained. .. code-block:: c char *block_ptr; if (k_mem_slab_alloc(&my_slab, &block_ptr, 100) == 0)) { memset(block_ptr, 0, 400); ... } else { printf("Memory allocation time-out"); } Releasing a Memory Block ======================== A memory block is released by calling :cpp:func:`k_mem_slab_free()`. The following code builds on the example above, and allocates a memory block, then releases it once it is no longer needed. .. code-block:: c char *block_ptr; k_mem_slab_alloc(&my_slab, &block_ptr, K_FOREVER); ... /* use memory block pointed at by block_ptr */ k_mem_slab_free(&my_slab, &block_ptr); Suggested Uses ************** Use a memory slab to allocate and free memory in fixed-size blocks. Use memory slab blocks when sending large amounts of data from one thread to another, to avoid unnecessary copying of the data. Configuration Options ********************* Related configuration options: * None. APIs **** The following memory slab APIs are provided by :file:`kernel.h`: * :cpp:func:`k_mem_slab_init()` * :cpp:func:`k_mem_slab_alloc()` * :cpp:func:`k_mem_slab_free()` * :cpp:func:`k_mem_slab_num_used_get()` * :cpp:func:`k_mem_slab_num_free_get()`