Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / support / CHIPMem.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18
19 /**
20  *    @file
21  *      This file defines heap memory allocation APIs for CHIP.
22  *
23  */
24
25 #pragma once
26
27 #include <core/CHIPError.h>
28 #include <stdlib.h>
29
30 #include <new>
31 #include <utility>
32
33 namespace chip {
34 namespace Platform {
35
36 #define CHIP_ZERO_AT(value)                                                                                                        \
37     do                                                                                                                             \
38     {                                                                                                                              \
39         memset(&value, 0, sizeof(value));                                                                                          \
40     } while (0)
41
42 /**
43  * This function is called by CHIP layer to initialize memory and resources
44  * required for proper functionality of the CHIP memory allocator.
45  * This function is platform specific and might be empty in certain cases.
46  * For example, this function is doing nothing when the C Standard Library malloc()
47  * and free() functions are used for memory allocation.
48  *
49  * @param[in]  buf      A pointer to a dedicated memory buffer, which should be used as
50  *                      a memory pool for CHIP memory allocation.
51  *                      This input is optional (defaults to NULL) and shouldn't be used
52  *                      if a dedicated memory buffer is not used.
53  *
54  * @param[in]  bufSize  Size of a dedicated memory buffer. This input is optional (defaults to 0)
55  *                      and shouldn't be used if dedicated memory buffer is not used.
56  *                      When a dedicated memory buffer is used the function checks and
57  *                      generates an error if buffer size is not big enough to support
58  *                      CHIP use cases.
59  *
60  * @retval  #CHIP_ERROR_BUFFER_TOO_SMALL  If dedicated input buffer size is not sufficient
61  *                                         to support CHIP use cases.
62  * @retval  #CHIP_NO_ERROR                On success.
63  * @retval  other                          An error generated by platform-specific memory
64  *                                         initialization function.
65  *
66  */
67 extern CHIP_ERROR MemoryInit(void * buf = nullptr, size_t bufSize = 0);
68
69 /**
70  * This function is called by the CHIP layer to releases all resources that were allocated
71  * by MemoryInit() function.
72  * This function can be an empty call if there is no need to release resources. For example,
73  * this is the case when the C Standard Library malloc() and free() functions are used
74  * for memory allocation.
75  *
76  */
77 extern void MemoryShutdown();
78
79 /**
80  * This function is called by the CHIP layer to allocate a block of memory of "size" bytes.
81  *
82  * @param[in]  size             Specifies requested memory size in bytes.
83  *
84  * @retval  Pointer to a memory block in case of success.
85  * @retval  NULL-pointer if memory allocation fails.
86  *
87  */
88 extern void * MemoryAlloc(size_t size);
89
90 /**
91  * This function is called by the CHIP layer to allocate a block of memory for an array of num
92  * elements, each of them size bytes long, and initializes all its bits to zero.
93  * The effective result is the allocation of a zero-initialized memory block of (num*size) bytes.
94  *
95  * @param[in]  num              Specifies number of elements to allocate.
96  * @param[in]  size             Specifies size of each element in bytes.
97  *
98  * @retval  Pointer to a memory block in case of success.
99  * @retval  NULL-pointer if memory allocation fails.
100  *
101  */
102 extern void * MemoryCalloc(size_t num, size_t size);
103
104 /**
105  * This function is called by the Chip layer to change the size of the memory block pointed to by p.
106  * The function may move the memory block to a new location (whose address is returned by the function).
107  * The content of the memory block is preserved up to the lesser of the new and old sizes, even if the
108  * block is moved to a new location. If the new size is larger, the value of the newly allocated portion
109  * is indeterminate.
110
111  * In case that p is a null pointer, the function behaves like malloc, assigning a new block of size bytes
112  * and returning a pointer to its beginning.
113  *
114  * @param[in]  p                Pointer to a memory block previously allocated with MemoryAlloc, MemoryCalloc
115  *                              or MemoryRealloc.
116  * @param[in]  size             Specifies new size for the memory block, in bytes..
117  *
118  * @retval  Pointer to a memory block in case of success.
119  * @retval  NULL-pointer if memory allocation fails.
120  *
121  */
122 extern void * MemoryRealloc(void * p, size_t size);
123
124 /**
125  * This function is called by the Chip layer to release a memory block allocated by
126  * the MemoryAlloc(), MemoryCalloc or MemoryRealloc.
127  * @param[in]  p                Pointer to a memory block that should be released.
128  *
129  */
130 extern void MemoryFree(void * p);
131
132 /**
133  * This function wraps the operator `new` with placement-new using MemoryAlloc().
134  * Instead of
135  *    p = new T(arguments)
136  * use
137  *    p = New<T>(arguments)
138  * In a few cases it may be necessary to add explicit casts to arguments, notably
139  * when passing integer constants to smaller integer parameters.
140  */
141 template <typename T, typename... Args>
142 inline T * New(Args &&... args)
143 {
144     void * p = MemoryAlloc(sizeof(T));
145     if (p != nullptr)
146     {
147         return new (p) T(std::forward<Args>(args)...);
148     }
149     return nullptr;
150 }
151
152 /**
153  * This function wraps the operator `delete` with using MemoryFree().
154  * Instead of
155  *    delete p
156  * use
157  *    Delete(p)
158  */
159 template <typename T>
160 inline void Delete(T * p)
161 {
162     p->~T();
163     MemoryFree(p);
164 }
165
166 // See MemoryDebugCheckPointer().
167 extern bool MemoryInternalCheckPointer(const void * p, size_t min_size);
168
169 /**
170  * In debug builds, test the validity of a pointer obtained from a chip::Platform memory allocation.
171  *
172  * @param[in]  p                Pointer to a memory block previously allocated with MemoryAlloc, MemoryCalloc,
173  *                              MemoryRealloc, or New, and not freed.
174  * @param[in]  min_size         Gives a size that the allocated block is expected to be able to hold.
175  *
176  * @e Unless configured with #CHIP_CONFIG_MEMORY_DEBUG_CHECKS, this function returns `true` without performing
177  * any check, inlined with the expectation that the compiler can remove any associated failure code.
178  *
179  * With #CHIP_CONFIG_MEMORY_DEBUG_CHECKS enabled:
180  *
181  * This function is guaranteed to return `false` if \a p is `nullptr`. The function returns `true` if \a p is a valid
182  * pointer to an allocation *and* the implementation memory manager is in a fully functioning state.
183  *
184  * @note For non-null \a p, the function *may* return `true` even if the pointer is invalid. That is, a particular
185  *       implementation or configuration is not guaranteed to catch any particular faulty state.
186  * @note For non-null \a p, the function return value *may* be incorrect if the memory manager is in a faulty state
187  *       (e.g. corrupt heap), even if the faulty state does not directly involve \a p.
188  * @note For non-null \a p, the function *may* abort the program rather than return at all if the memory manager is in
189  *       a faulty state, even if \a p is valid.
190  * @note For a non-null \a p, checking *may* be slow.
191  *
192  *
193  * @return  An implementation- and configuration-defined estimate of whether \a p is a valid allocated pointer.
194  */
195 inline bool MemoryDebugCheckPointer(const void * p, size_t min_size = 0)
196 {
197 #if CHIP_CONFIG_MEMORY_DEBUG_CHECKS
198     return MemoryInternalCheckPointer(p, min_size);
199 #else  // CHIP_CONFIG_MEMORY_DEBUG_CHECKS
200     return true;
201 #endif // CHIP_CONFIG_MEMORY_DEBUG_CHECKS
202 }
203
204 } // namespace Platform
205 } // namespace chip