1.. _heap_v2:
2
3Memory Heaps
4############
5
6Zephyr provides a collection of utilities that allow threads to
7dynamically allocate memory.
8
9Synchronized Heap Allocator
10***************************
11
12Creating a Heap
13===============
14
15The simplest way to define a heap is statically, with the
16:c:macro:`K_HEAP_DEFINE` macro.  This creates a static :c:struct:`k_heap` variable
17with a given name that manages a memory region of the
18specified size.
19
20Heaps can also be created to manage arbitrary regions of
21application-controlled memory using :c:func:`k_heap_init`.
22
23Allocating Memory
24=================
25
26Memory can be allocated from a heap using :c:func:`k_heap_alloc`,
27passing it the address of the heap object and the number of bytes
28desired.  This functions similarly to standard C ``malloc()``,
29returning a NULL pointer on an allocation failure.
30
31The heap supports blocking operation, allowing threads to go to sleep
32until memory is available.  The final argument is a
33:c:type:`k_timeout_t` timeout value indicating how long the thread may
34sleep before returning, or else one of the constant timeout values
35:c:macro:`K_NO_WAIT` or :c:macro:`K_FOREVER`.
36
37Releasing Memory
38================
39
40Memory allocated with :c:func:`k_heap_alloc` must be released using
41:c:func:`k_heap_free`.  Similar to standard C ``free()``, the pointer
42provided must be either a ``NULL`` value or a pointer previously
43returned by :c:func:`k_heap_alloc` for the same heap.  Freeing a
44``NULL`` value is defined to have no effect.
45
46Low Level Heap Allocator
47************************
48
49The underlying implementation of the :c:struct:`k_heap`
50abstraction is provided a data structure named :c:struct:`sys_heap`.  This
51implements exactly the same allocation semantics, but
52provides no kernel synchronization tools.  It is available for
53applications that want to manage their own blocks of memory in
54contexts (for example, userspace) where synchronization is unavailable
55or more complicated.  Unlike ``k_heap``, all calls to any ``sys_heap``
56functions on a single heap must be serialized by the caller.
57Simultaneous use from separate threads is disallowed.
58
59Implementation
60==============
61
62Internally, the ``sys_heap`` memory block is partitioned into "chunks"
63of 8 bytes.  All allocations are made out of a contiguous region of
64chunks.  The first chunk of every allocation or unused block is
65prefixed by a chunk header that stores the length of the chunk, the
66length of the next lower ("left") chunk in physical memory, a bit
67indicating whether the chunk is in use, and chunk-indexed link
68pointers to the previous and next chunk in a "free list" to which
69unused chunks are added.
70
71The heap code takes reasonable care to avoid fragmentation.  Free
72block lists are stored in "buckets" by their size, each bucket storing
73blocks within one power of two (i.e. a bucket for blocks of 3-4
74chunks, another for 5-8, 9-16, etc...) this allows new allocations to
75be made from the smallest/most-fragmented blocks available.  Also, as
76allocations are freed and added to the heap, they are automatically
77combined with adjacent free blocks to prevent fragmentation.
78
79All metadata is stored at the beginning of the contiguous block of
80heap memory, including the variable-length list of bucket list heads
81(which depend on heap size).  The only external memory required is the
82:c:struct:`sys_heap` structure itself.
83
84The ``sys_heap`` functions are unsynchronized.  Care must be taken by
85any users to prevent concurrent access.  Only one context may be
86inside one of the API functions at a time.
87
88The heap code takes care to present high performance and reliable
89latency.  All ``sys_heap`` API functions are guaranteed to complete
90within constant time.  On typical architectures, they will all
91complete within 1-200 cycles.  One complexity is that the search of
92the minimum bucket size for an allocation (the set of free blocks that
93"might fit") has a compile-time upper bound of iterations to prevent
94unbounded list searches, at the expense of some fragmentation
95resistance.  This :kconfig:option:`CONFIG_SYS_HEAP_ALLOC_LOOPS` value may be
96chosen by the user at build time, and defaults to a value of 3.
97
98Multi-Heap Wrapper Utility
99**************************
100
101The ``sys_heap`` utility requires that all managed memory be in a
102single contiguous block.  It is common for complicated microcontroller
103applications to have more complicated memory setups that they still
104want to manage dynamically as a "heap".  For example, the memory might
105exist as separate discontiguous regions, different areas may have
106different cache, performance or power behavior, peripheral devices may
107only be able to perform DMA to certain regions, etc...
108
109For those situations, Zephyr provides a ``sys_multi_heap`` utility.
110Effectively this is a simple wrapper around a set of one or more
111``sys_heap`` objects.  It should be initialized after its child heaps
112via :c:func:`sys_multi_heap_init`, after which each heap can be added
113to the managed set via :c:func:`sys_multi_heap_add_heap`.  No
114destruction utility is provided; just as for ``sys_heap``,
115applications that want to destroy a multi heap should simply ensure
116all allocated blocks are freed (or at least will never be used again)
117and repurpose the underlying memory for another usage.
118
119It has a single pair of allocation entry points,
120:c:func:`sys_multi_heap_alloc` and
121:c:func:`sys_multi_heap_aligned_alloc`.  These behave identically to
122the ``sys_heap`` functions with similar names, except that they also
123accept an opaque "configuration" parameter.  This pointer is
124uninspected by the multi heap code itself; instead it is passed to a
125callback function provided at initialization time.  This
126application-provided callback is responsible for doing the underlying
127allocation from one of the managed heaps, and may use the
128configuration parameter in any way it likes to make that decision.
129
130For modifying the size of an allocated buffer (whether shrinking
131or enlarging it), you can use the
132:c:func:`sys_multi_heap_realloc` and
133:c:func:`sys_multi_heap_aligned_realloc` APIs.  If the buffer cannot be
134enlarged on the heap where it currently resides,
135any of the eligible heaps specified by the configuration parameter may be used.
136
137When unused, a multi heap may be freed via
138:c:func:`sys_multi_heap_free`.  The application does not need to pass
139a configuration parameter.  Memory allocated from any of the managed
140``sys_heap`` objects may be freed with in the same way.
141
142System Heap
143***********
144
145The :dfn:`system heap` is a predefined memory allocator that allows
146threads to dynamically allocate memory from a common memory region in
147a :c:func:`malloc`-like manner.
148
149Only a single system heap is defined. Unlike other heaps or memory
150pools, the system heap cannot be directly referenced using its
151memory address.
152
153The size of the system heap is configurable to arbitrary sizes,
154subject to space availability.
155
156A thread can dynamically allocate a chunk of heap memory by calling
157:c:func:`k_malloc`. The address of the allocated chunk is
158guaranteed to be aligned on a multiple of pointer sizes. If a suitable
159chunk of heap memory cannot be found ``NULL`` is returned.
160
161When the thread is finished with a chunk of heap memory it can release
162the chunk back to the system heap by calling :c:func:`k_free`.
163
164Defining the Heap Memory Pool
165=============================
166
167The size of the heap memory pool is specified using the
168:kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE` configuration option.
169
170By default, the heap memory pool size is zero bytes. This value instructs
171the kernel not to define the heap memory pool object. The maximum size is limited
172by the amount of available memory in the system. The project build will fail in
173the link stage if the size specified can not be supported.
174
175In addition, each subsystem (board, driver, library, etc) can set a custom
176requirement by defining a Kconfig option with the prefix
177``HEAP_MEM_POOL_ADD_SIZE_`` (this value is in bytes). If multiple subsystems
178specify custom values, the sum of these will be used as the minimum requirement.
179If the application tries to set a value that's less than the minimum value, this
180will be ignored and the minimum value will be used instead.
181
182To force a smaller than minimum value to be used, the application may enable the
183:kconfig:option:`CONFIG_HEAP_MEM_POOL_IGNORE_MIN` option. This can be useful
184when optimizing the heap size and the minimum requirement can be more accurately
185determined for a specific application.
186
187Allocating Memory
188=================
189
190A chunk of heap memory is allocated by calling :c:func:`k_malloc`.
191
192The following code allocates a 200 byte chunk of heap memory, then fills it
193with zeros. A warning is issued if a suitable chunk is not obtained.
194
195.. code-block:: c
196
197    char *mem_ptr;
198
199    mem_ptr = k_malloc(200);
200    if (mem_ptr != NULL)) {
201        memset(mem_ptr, 0, 200);
202	...
203    } else {
204        printf("Memory not allocated");
205    }
206
207Releasing Memory
208================
209
210A chunk of heap memory is released by calling :c:func:`k_free`.
211
212The following code allocates a 75 byte chunk of memory, then releases it
213once it is no longer needed.
214
215.. code-block:: c
216
217    char *mem_ptr;
218
219    mem_ptr = k_malloc(75);
220    ... /* use memory block */
221    k_free(mem_ptr);
222
223Suggested Uses
224==============
225
226Use the heap memory pool to dynamically allocate memory in a
227:c:func:`malloc`-like manner.
228
229Configuration Options
230=====================
231
232Related configuration options:
233
234* :kconfig:option:`CONFIG_HEAP_MEM_POOL_SIZE`
235
236API Reference
237=============
238
239.. doxygengroup:: heap_apis
240
241.. doxygengroup:: low_level_heap_allocator
242
243.. doxygengroup:: multi_heap_wrapper
244
245Heap listener
246*************
247
248.. doxygengroup:: heap_listener_apis
249