1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef FWK_MM_H 9 #define FWK_MM_H 10 11 #include <fwk_attributes.h> 12 13 #include <stddef.h> 14 #include <stdlib.h> 15 #include <string.h> 16 17 /*! 18 * \addtogroup GroupLibFramework Framework 19 * \{ 20 */ 21 22 /*! 23 * \addtogroup GroupMM Memory Management 24 * 25 * \brief Memory management interface. 26 * 27 * \details The memory management interface augments the standard C library 28 * memory allocation functions with a slightly more consistent interface 29 * and stronger portability guarantees across the variety of systems that 30 * the framework supports. 31 * 32 * \{ 33 */ 34 35 /*! 36 * \brief Allocates memory for an array of `num` objects of `size`. 37 * 38 * \details If allocation succeeds, returns a pointer that is suitably aligned 39 * for any object type with fundamental alignment. 40 * 41 * \details If the product of `num` and `size` is zero, the behavior of 42 * ::fwk_mm_alloc() is implementation-defined. 43 * 44 * \note ::fwk_mm_alloc() is thread-safe: it behaves as though only accessing 45 * the memory locations visible through its argument, and not any static 46 * storage. 47 * 48 * \note A previous call to ::fwk_mm_free() or ::fwk_mm_realloc() that 49 * deallocates a region of memory synchronizes-with a call to 50 * ::fwk_mm_alloc() that allocates the same or a part of the same region 51 * of memory. This synchronization occurs after any access to the memory 52 * by the deallocating function and before any access to the memory by 53 * ::fwk_mm_alloc(). There is a single total order of all allocation and 54 * deallocation functions operating on each particular region of memory. 55 * 56 * \note This function, semantically, behaves identically to `malloc()`. 57 * 58 * \param[in] num Number of objects. 59 * \param[in] size Size of each object. 60 * 61 * \return On success, returns the pointer to the beginning of newly allocated 62 * memory. To avoid a memory leak, the returned pointer must be 63 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). 64 * 65 * \return On failure, traps. 66 */ 67 FWK_LEAF FWK_NOTHROW FWK_ALLOC FWK_ALLOC_SIZE2(1, 2) FWK_WARN_UNUSED 68 void *fwk_mm_alloc(size_t num, size_t size); 69 70 /*! 71 * \brief Allocates memory for an array of `num` objects of `size`. Does not 72 * trap on failure. 73 * 74 * \details Identical to fwk_mm_alloc(), but does not trap. 75 * 76 * \param[in] num Number of objects. 77 * \param[in] size Size of each object. 78 * 79 * \return On success, returns the pointer to the beginning of newly allocated 80 * memory. To avoid a memory leak, the returned pointer must be 81 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). 82 * 83 * \return On failure, returns a null pointer. 84 */ 85 FWK_LEAF FWK_NOTHROW FWK_ALLOC FWK_ALLOC_SIZE2(1, 2) FWK_WARN_UNUSED 86 void *fwk_mm_alloc_notrap(size_t num, size_t size); 87 88 /*! 89 * \brief Allocates memory for an array of `num` objects of `size` whose 90 * alignment is specified by `alignment`. The product of the `num` and 91 * `size` parameters must be an integral multiple of `alignment`. 92 * 93 * \details ::fwk_mm_alloc_aligned() is thread-safe: it behaves as though only 94 * accessing the memory locations visible through its argument, and not 95 * any static storage. 96 * 97 * \details A previous call to ::fwk_mm_free() or ::fwk_mm_realloc() that 98 * deallocates a region of memory synchronizes-with a call to 99 * ::fwk_mm_alloc_aligned() that allocates the same or a part of the same 100 * region of memory. This synchronization occurs after any access to the 101 * memory by the deallocating function and before any access to the memory 102 * by ::fwk_mm_alloc_aligned(). There is a single total order of all 103 * allocation and deallocation functions operating on each particular 104 * region of memory. 105 * 106 * \note This function, semantically, behaves identically to 107 * `aligned_alloc()`. 108 * 109 * \param[in] alignment Specifies the alignment. Must be a valid alignment 110 * supported by the implementation. 111 * \param[in] num Number of objects. 112 * \param[in] size Size of each object. An integral multiple of `alignment`. 113 * 114 * \return On success, returns the pointer to the beginning of newly allocated 115 * memory. To avoid a memory leak, the returned pointer must be 116 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). 117 * 118 * \return On failure, traps. 119 */ 120 FWK_LEAF 121 FWK_NOTHROW FWK_ALLOC FWK_ALLOC_ALIGN(1) FWK_ALLOC_SIZE2(2, 3) FWK_WARN_UNUSED 122 void *fwk_mm_alloc_aligned(size_t alignment, size_t num, size_t size); 123 124 /*! 125 * \brief Allocates memory for an array of `num` objects of `size` and 126 * initializes all bytes in the allocated storage to zero. 127 * 128 * \details If allocation succeeds, returns a pointer to the lowest (first) 129 * byte in the allocated memory block that is suitably aligned for any 130 * object type. 131 * 132 * \details If the product of `num` and `size` is zero, the behavior is 133 * implementation-defined. 134 * 135 * \note ::fwk_mm_calloc() is thread-safe: it behaves as though only accessing 136 * the memory locations visible through its argument, and not any static 137 * storage. 138 * 139 * \note A previous call to ::fwk_mm_free() or ::fwk_mm_realloc() that 140 * deallocates a region of memory synchronizes-with a call to 141 * ::fwk_mm_calloc() that allocates the same or a part of the same region 142 * of memory. This synchronization occurs after any access to the memory 143 * by the deallocating function and before any access to the memory by 144 * ::fwk_mm_calloc(). There is a single total order of all allocation and 145 * deallocation functions operating on each particular region of memory. 146 * 147 * \note This function, semantically, behaves identically to `calloc()`. 148 * 149 * \param[in] num Number of objects. 150 * \param[in] size Size of each object. 151 * 152 * \return On success, returns the pointer to the beginning of newly allocated 153 * memory. To avoid a memory leak, the returned pointer must be 154 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). 155 * 156 * \return On failure, traps. 157 */ 158 FWK_LEAF FWK_NOTHROW FWK_ALLOC FWK_ALLOC_SIZE2(1, 2) FWK_WARN_UNUSED 159 void *fwk_mm_calloc(size_t num, size_t size); 160 161 /*! 162 * \brief Allocates memory for an array of num objects of size whose alignment 163 * is specified by `alignment` and initializes all bytes in the allocated 164 * storage to zero. 165 * 166 * \details ::fwk_mm_alloc_aligned() is thread-safe: it behaves as though only 167 * accessing the memory locations visible through its argument, and not 168 * any static storage. 169 * 170 * \details A previous call to ::fwk_mm_free() or ::fwk_mm_realloc() that 171 * deallocates a region of memory synchronizes-with a call to 172 * ::fwk_mm_calloc_aligned() that allocates the same or a part of the same 173 * region of memory. This synchronization occurs after any access to the 174 * memory by the deallocating function and before any access to the memory 175 * by ::fwk_mm_calloc_aligned(). There is a single total order of all 176 * allocation and deallocation functions operating on each particular 177 * region of memory. 178 * 179 * \param[in] alignment Specifies the alignment. Must be a valid alignment 180 * supported by the implementation. 181 * \param[in] num Number of objects. 182 * \param[in] size Size of each object. 183 * 184 * \return On success, returns the pointer to the beginning of newly allocated 185 * memory. To avoid a memory leak, the returned pointer must be 186 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). 187 * 188 * \return On failure, traps. 189 */ 190 FWK_LEAF 191 FWK_NOTHROW FWK_ALLOC FWK_ALLOC_ALIGN(1) FWK_ALLOC_SIZE2(2, 3) FWK_WARN_UNUSED 192 void *fwk_mm_calloc_aligned(size_t alignment, size_t num, size_t size); 193 194 /*! 195 * \brief Reallocates the given area of memory. It must be previously 196 * allocated by ::fwk_mm_alloc, ::fwk_mm_alloc_aligned, ::fwk_mm_calloc, 197 * ::fwk_mm_calloc_aligned, or ::fwk_mm_realloc and not yet freed with a 198 * call to ::fwk_mm_free or ::fwk_mm_realloc. Otherwise, the results are 199 * undefined. 200 * 201 * \details The reallocation is done by either: 202 * * expanding or contracting the existing area pointed to by `ptr`, 203 * if possible. The contents of the area remain unchanged up to the 204 * lesser of the new and old sizes. If the area is expanded, the 205 * contents of the new part of the array are undefined. 206 * * allocating a new memory block of size `new_size` bytes, copying 207 * memory area with size equal the lesser of the new and the old 208 * sizes, and freeing the old block. 209 * 210 * \details If there is not enough memory, the old memory block is not freed 211 * and null pointer is returned. 212 * 213 * \details If `ptr` is `NULL`, the behavior is the same as calling 214 * `fwk_mm_alloc(new_size)`. 215 * 216 * \details If `new_size` is zero, the behavior is implementation defined (null 217 * pointer may be returned (in which case the old memory block may or may 218 * not be freed), or some non-null pointer may be returned that may not be 219 * used to access storage). 220 * 221 * \note ::fwk_mm_realloc() is thread-safe: it behaves as though only accessing 222 * the memory locations visible through its argument, and not any static 223 * storage. 224 * 225 * \note A previous call to ::fwk_mm_free() or ::fwk_mm_realloc() that 226 * deallocates a region of memory synchronizes-with a call to any 227 * allocation function, including ::fwk_mm_realloc() that allocates the 228 * same or a part of the same region of memory. This synchronization 229 * occurs after any access to the memory by the deallocating function and 230 * before any access to the memory by ::fwk_mm_realloc(). There is a 231 * single total order of all allocation and deallocation functions 232 * operating on each particular region of memory. 233 * 234 * \note This function, semantically, behaves identically to `realloc()`. 235 * 236 * \param[in] ptr Pointer to the memory area to be reallocated. 237 * \param[in] num Number of objects. 238 * \param[in] size Size of each object. 239 * 240 * \return On success, returns the pointer to the beginning of newly allocated 241 * memory. To avoid a memory leak, the returned pointer must be 242 * deallocated with ::fwk_mm_free() or ::fwk_mm_realloc(). The original 243 * pointer `ptr` is invalidated and any access to it is undefined behavior 244 * (even if reallocation was in-place). 245 * 246 * \return On failure, returns a null pointer. The original pointer `ptr` 247 * remains valid and may need to be deallocated with ::fwk_mm_free() or 248 * ::fwk_mm_realloc(). 249 */ 250 FWK_LEAF FWK_NOTHROW FWK_ALLOC_SIZE2(2, 3) FWK_WARN_UNUSED 251 void *fwk_mm_realloc(void *ptr, size_t num, size_t size); 252 253 /*! 254 * \brief Deallocates the space previously allocated by ::fwk_mm_alloc(), 255 * ::fwk_mm_calloc(), ::fwk_mm_alloc_aligned(), ::fwk_mm_calloc_aligned(), 256 * or ::fwk_mm_realloc(). 257 * 258 * \details If `ptr` is a null pointer, the function does nothing. 259 * 260 * \details The behavior is undefined if the value of `ptr` does not equal a 261 * value returned earlier by ::fwk_mm_alloc(), ::fwk_mm_calloc(), 262 * ::fwk_mm_realloc(), ::fwk_mm_alloc_aligned(), or 263 * ::fwk_mm_calloc_aligned(). 264 * 265 * \details The behavior is undefined if the memory area referred to by `ptr` 266 * has already been deallocated, that is, ::fwk_mm_free() or 267 * ::fwk_mm_realloc() has already been called with `ptr` as the argument 268 * and no calls to ::fwk_mm_alloc(), ::fwk_mm_calloc(), 269 * ::fwk_mm_alloc_aligned(), ::fwk_mm_calloc_aligned(), or 270 * ::fwk_mm_realloc() resulted in a pointer equal to `ptr` afterwards. 271 * 272 * \note This function, semantically, behaves identically to `free()`. 273 * 274 * \param[in] ptr Pointer to the block of memory to free. 275 */ 276 FWK_LEAF FWK_NOTHROW void fwk_mm_free(void *ptr); 277 278 /*! 279 * \} 280 */ 281 282 /*! 283 * \} 284 */ 285 286 #endif /* FWK_MM_H */ 287