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