1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #pragma once 7 #include <stdint.h> 8 #include <stdlib.h> 9 #include <stdbool.h> 10 11 /* multi_heap is a heap implementation for handling multiple 12 heterogenous heaps in a single program. 13 14 Any contiguous block of memory can be registered as a heap. 15 */ 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 /** @brief Opaque handle to a registered heap */ 22 typedef struct multi_heap_info *multi_heap_handle_t; 23 24 /** 25 * @brief allocate a chunk of memory with specific alignment 26 * 27 * @param heap Handle to a registered heap. 28 * @param size size in bytes of memory chunk 29 * @param alignment how the memory must be aligned 30 * 31 * @return pointer to the memory allocated, NULL on failure 32 */ 33 void *multi_heap_aligned_alloc(multi_heap_handle_t heap, size_t size, size_t alignment); 34 35 /** @brief malloc() a buffer in a given heap 36 * 37 * Semantics are the same as standard malloc(), only the returned buffer will be allocated in the specified heap. 38 * 39 * @param heap Handle to a registered heap. 40 * @param size Size of desired buffer. 41 * 42 * @return Pointer to new memory, or NULL if allocation fails. 43 */ 44 void *multi_heap_malloc(multi_heap_handle_t heap, size_t size); 45 46 /** @brief free() a buffer aligned in a given heap. 47 * 48 * @param heap Handle to a registered heap. 49 * @param p NULL, or a pointer previously returned from multi_heap_aligned_alloc() for the same heap. 50 * @note This function is deprecated, consider using multi_heap_free() instead 51 */ 52 void __attribute__((deprecated)) multi_heap_aligned_free(multi_heap_handle_t heap, void *p); 53 54 /** @brief free() a buffer in a given heap. 55 * 56 * Semantics are the same as standard free(), only the argument 'p' must be NULL or have been allocated in the specified heap. 57 * 58 * @param heap Handle to a registered heap. 59 * @param p NULL, or a pointer previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. 60 */ 61 void multi_heap_free(multi_heap_handle_t heap, void *p); 62 63 /** @brief realloc() a buffer in a given heap. 64 * 65 * Semantics are the same as standard realloc(), only the argument 'p' must be NULL or have been allocated in the specified heap. 66 * 67 * @param heap Handle to a registered heap. 68 * @param p NULL, or a pointer previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. 69 * @param size Desired new size for buffer. 70 * 71 * @return New buffer of 'size' containing contents of 'p', or NULL if reallocation failed. 72 */ 73 void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size); 74 75 76 /** @brief Return the size that a particular pointer was allocated with. 77 * 78 * @param heap Handle to a registered heap. 79 * @param p Pointer, must have been previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. 80 * 81 * @return Size of the memory allocated at this block. May be more than the original size argument, due 82 * to padding and minimum block sizes. 83 */ 84 size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p); 85 86 87 /** @brief Register a new heap for use 88 * 89 * This function initialises a heap at the specified address, and returns a handle for future heap operations. 90 * 91 * There is no equivalent function for deregistering a heap - if all blocks in the heap are free, you can immediately start using the memory for other purposes. 92 * 93 * @param start Start address of the memory to use for a new heap. 94 * @param size Size (in bytes) of the new heap. 95 * 96 * @return Handle of a new heap ready for use, or NULL if the heap region was too small to be initialised. 97 */ 98 multi_heap_handle_t multi_heap_register(void *start, size_t size); 99 100 101 /** @brief Associate a private lock pointer with a heap 102 * 103 * The lock argument is supplied to the MULTI_HEAP_LOCK() and MULTI_HEAP_UNLOCK() macros, defined in multi_heap_platform.h. 104 * 105 * The lock in question must be recursive. 106 * 107 * When the heap is first registered, the associated lock is NULL. 108 * 109 * @param heap Handle to a registered heap. 110 * @param lock Optional pointer to a locking structure to associate with this heap. 111 */ 112 void multi_heap_set_lock(multi_heap_handle_t heap, void* lock); 113 114 /** @brief Dump heap information to stdout 115 * 116 * For debugging purposes, this function dumps information about every block in the heap to stdout. 117 * 118 * @param heap Handle to a registered heap. 119 */ 120 void multi_heap_dump(multi_heap_handle_t heap); 121 122 /** @brief Check heap integrity 123 * 124 * Walks the heap and checks all heap data structures are valid. If any errors are detected, an error-specific message 125 * can be optionally printed to stderr. Print behaviour can be overridden at compile time by defining 126 * MULTI_CHECK_FAIL_PRINTF in multi_heap_platform.h. 127 * 128 * @note This function is not thread-safe as it sets a global variable with the value of print_errors. 129 * 130 * @param heap Handle to a registered heap. 131 * @param print_errors If true, errors will be printed to stderr. 132 * @return true if heap is valid, false otherwise. 133 */ 134 bool multi_heap_check(multi_heap_handle_t heap, bool print_errors); 135 136 /** @brief Return free heap size 137 * 138 * Returns the number of bytes available in the heap. 139 * 140 * Equivalent to the total_free_bytes member returned by multi_heap_get_heap_info(). 141 * 142 * Note that the heap may be fragmented, so the actual maximum size for a single malloc() may be lower. To know this 143 * size, see the largest_free_block member returned by multi_heap_get_heap_info(). 144 * 145 * @param heap Handle to a registered heap. 146 * @return Number of free bytes. 147 */ 148 size_t multi_heap_free_size(multi_heap_handle_t heap); 149 150 /** @brief Return the lifetime minimum free heap size 151 * 152 * Equivalent to the minimum_free_bytes member returned by multi_heap_get_info(). 153 * 154 * Returns the lifetime "low watermark" of possible values returned from multi_free_heap_size(), for the specified 155 * heap. 156 * 157 * @param heap Handle to a registered heap. 158 * @return Number of free bytes. 159 */ 160 size_t multi_heap_minimum_free_size(multi_heap_handle_t heap); 161 162 /** @brief Structure to access heap metadata via multi_heap_get_info */ 163 typedef struct { 164 size_t total_free_bytes; ///< Total free bytes in the heap. Equivalent to multi_free_heap_size(). 165 size_t total_allocated_bytes; ///< Total bytes allocated to data in the heap. 166 size_t largest_free_block; ///< Size of the largest free block in the heap. This is the largest malloc-able size. 167 size_t minimum_free_bytes; ///< Lifetime minimum free heap size. Equivalent to multi_minimum_free_heap_size(). 168 size_t allocated_blocks; ///< Number of (variable size) blocks allocated in the heap. 169 size_t free_blocks; ///< Number of (variable size) free blocks in the heap. 170 size_t total_blocks; ///< Total number of (variable size) blocks in the heap. 171 } multi_heap_info_t; 172 173 /** @brief Return metadata about a given heap 174 * 175 * Fills a multi_heap_info_t structure with information about the specified heap. 176 * 177 * @param heap Handle to a registered heap. 178 * @param info Pointer to a structure to fill with heap metadata. 179 */ 180 void multi_heap_get_info(multi_heap_handle_t heap, multi_heap_info_t *info); 181 182 #ifdef __cplusplus 183 } 184 #endif 185