3 * Copyright (c) 2020-2021 Project CHIP Authors
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * This file defines heap memory allocation APIs for CHIP.
27 #include <core/CHIPError.h>
36 #define CHIP_ZERO_AT(value) \
39 memset(&value, 0, sizeof(value)); \
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.
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.
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
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.
67 extern CHIP_ERROR MemoryInit(void * buf = nullptr, size_t bufSize = 0);
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.
77 extern void MemoryShutdown();
80 * This function is called by the CHIP layer to allocate a block of memory of "size" bytes.
82 * @param[in] size Specifies requested memory size in bytes.
84 * @retval Pointer to a memory block in case of success.
85 * @retval NULL-pointer if memory allocation fails.
88 extern void * MemoryAlloc(size_t size);
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.
95 * @param[in] num Specifies number of elements to allocate.
96 * @param[in] size Specifies size of each element in bytes.
98 * @retval Pointer to a memory block in case of success.
99 * @retval NULL-pointer if memory allocation fails.
102 extern void * MemoryCalloc(size_t num, size_t size);
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
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.
114 * @param[in] p Pointer to a memory block previously allocated with MemoryAlloc, MemoryCalloc
116 * @param[in] size Specifies new size for the memory block, in bytes..
118 * @retval Pointer to a memory block in case of success.
119 * @retval NULL-pointer if memory allocation fails.
122 extern void * MemoryRealloc(void * p, size_t size);
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.
130 extern void MemoryFree(void * p);
133 * This function wraps the operator `new` with placement-new using MemoryAlloc().
135 * p = new T(arguments)
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.
141 template <typename T, typename... Args>
142 inline T * New(Args &&... args)
144 void * p = MemoryAlloc(sizeof(T));
147 return new (p) T(std::forward<Args>(args)...);
153 * This function wraps the operator `delete` with using MemoryFree().
159 template <typename T>
160 inline void Delete(T * p)
166 // See MemoryDebugCheckPointer().
167 extern bool MemoryInternalCheckPointer(const void * p, size_t min_size);
170 * In debug builds, test the validity of a pointer obtained from a chip::Platform memory allocation.
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.
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.
179 * With #CHIP_CONFIG_MEMORY_DEBUG_CHECKS enabled:
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.
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.
193 * @return An implementation- and configuration-defined estimate of whether \a p is a valid allocated pointer.
195 inline bool MemoryDebugCheckPointer(const void * p, size_t min_size = 0)
197 #if CHIP_CONFIG_MEMORY_DEBUG_CHECKS
198 return MemoryInternalCheckPointer(p, min_size);
199 #else // CHIP_CONFIG_MEMORY_DEBUG_CHECKS
201 #endif // CHIP_CONFIG_MEMORY_DEBUG_CHECKS
204 } // namespace Platform