/* Copyright (c) 2021 Intel Corporation * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_SYS_MULTI_HEAP_H_ #define ZEPHYR_INCLUDE_SYS_MULTI_HEAP_H_ #include #define MAX_MULTI_HEAPS 8 /** * @brief Multi-heap allocator * * A sys_multi_heap represents a single allocator made from multiple, * separately managed pools of memory that must be accessed via a * unified API. They can be discontiguous, and in many cases will be * expected to have different capabilities (for example: latency, * cacheability, cpu affinity, etc...) * * Allocation from the multiheap provides an opaque "configuration" * value to specify requirements and heuristics to assist the choice * in backend, which is then provided to a user-specified "choice" * function whose job it is to select a heap based on information in * the config specifier and runtime state (heap full state, etc...) */ struct sys_multi_heap; /** * @brief Multi-heap choice function * * This is a user-provided functions whose responsibility is selecting * a specific sys_heap backend based on the opaque cfg value, which is * specified by the user as an argument to sys_multi_heap_alloc(), and * performing the allocation on behalf of the caller. The callback is * free to choose any registered heap backend to perform the * allocation, and may choose to pad the user-provided values as * needed, and to use an aligned allocation where required by the * specified configuration. * * NULL may be returned, which will cause the * allocation to fail and a NULL reported to the calling code. * * @param mheap Multi-heap structure. * @param cfg An opaque user-provided value. It may be interpreted in * any way by the application * @param align Alignment of requested memory (or zero for no alignment) * @param size The user-specified allocation size in bytes * @return A pointer to the allocated memory */ typedef void *(*sys_multi_heap_fn_t)(struct sys_multi_heap *mheap, void *cfg, size_t align, size_t size); struct sys_multi_heap { int nheaps; sys_multi_heap_fn_t choice; struct sys_heap *heaps[MAX_MULTI_HEAPS]; }; /** * @brief Initialize multi-heap * * Initialize a sys_multi_heap struct with the specified choice * function. Note that individual heaps must be added later with * sys_multi_heap_add_heap so that the heap bounds can be tracked by * the multi heap code. * * @note In general a multiheap is likely to be instantiated * semi-statically from system configuration (for example, via * linker-provided bounds on available memory in different regions, or * from devicetree definitions of hardware-provided addressible * memory, etc...). The general expectation is that a soc- or * board-level platform device will be initialized at system boot from * these upstream configuration sources and not that an application * will assemble a multi-heap on its own. * * @param heap A sys_multi_heap to initialize * @param choice_fn A sys_multi_heap_fn_t callback used to select * heaps at allocation time */ void sys_multi_heap_init(struct sys_multi_heap *heap, sys_multi_heap_fn_t choice_fn); /** * @brief Add sys_heap to multi heap * * This adds a known sys_heap backend to an existing multi heap, * allowing the multi heap internals to track the bounds of the heap * and determine which heap (if any) from which a freed block was * allocated. * * @param mheap A sys_multi_heap to which to add a heap * @param heap The heap to add */ void sys_multi_heap_add_heap(struct sys_multi_heap *mheap, struct sys_heap *heap); /** * @brief Allocate memory from multi heap * * Just as for sys_heap_alloc(), allocates a block of memory of the * specified size in bytes. Takes an opaque configuration pointer * passed to the multi heap choice function, which is used by * integration code to choose a heap backend. * * @param mheap Multi heap pointer * @param cfg Opaque configuration parameter, as for sys_multi_heap_fn_t * @param bytes Requested size of the allocation, in bytes * @return A valid pointer to heap memory, or NULL if no memory is available */ void *sys_multi_heap_alloc(struct sys_multi_heap *mheap, void *cfg, size_t bytes); /** * @brief Allocate aligned memory from multi heap * * Just as for sys_multi_heap_alloc(), allocates a block of memory of * the specified size in bytes. Takes an additional parameter * specifying a power of two alignment, in bytes. * * @param mheap Multi heap pointer * @param cfg Opaque configuration parameter, as for sys_multi_heap_fn_t * @param align Power of two alignment for the returned pointer, in bytes * @param bytes Requested size of the allocation, in bytes * @return A valid pointer to heap memory, or NULL if no memory is available */ void *sys_multi_heap_aligned_alloc(struct sys_multi_heap *mheap, void *cfg, size_t align, size_t bytes); /** * @brief Free memory allocated from multi heap * * Returns the specified block, which must be the return value of a * previously successful sys_multi_heap_alloc() or * sys_multi_heap_aligned_alloc() call, to the heap backend from which * it was allocated. * * Accepts NULL as a block parameter, which is specified to have no * effect. * * @param mheap Multi heap pointer * @param block Block to free */ void sys_multi_heap_free(struct sys_multi_heap *mheap, void *block); #endif /* ZEPHYR_INCLUDE_SYS_MULTI_HEAP_H_ */