Line data Source code
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 implements heap memory allocation APIs for CHIP. These functions are platform
22 : * specific and might be C Standard Library heap functions re-direction in most of cases.
23 : *
24 : */
25 :
26 : #include <lib/core/CHIPConfig.h>
27 : #include <lib/support/CHIPMem.h>
28 : #include <lib/support/VerificationMacrosNoLogging.h>
29 :
30 : #include <stdlib.h>
31 :
32 : #ifndef NDEBUG
33 : #include <atomic>
34 : #include <cstdio>
35 : #endif
36 :
37 : #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
38 : #include <dmalloc.h>
39 : #include <lib/support/SafeInt.h>
40 : #endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
41 :
42 : #if CHIP_CONFIG_MEMORY_MGMT_MALLOC
43 :
44 : namespace chip {
45 : namespace Platform {
46 :
47 : #ifdef NDEBUG
48 :
49 : #define VERIFY_INITIALIZED()
50 : #define VERIFY_POINTER(p)
51 :
52 : #else
53 :
54 : #define VERIFY_INITIALIZED() VerifyInitialized(__func__)
55 :
56 : static std::atomic_int memoryInitialized{ 0 };
57 :
58 27327476 : static void VerifyInitialized(const char * func)
59 : {
60 : // Logging can use Memory::Alloc, so we can't use logging with our
61 : // VerifyOrDie bits here.
62 27327476 : VerifyOrDieWithoutLogging(memoryInitialized);
63 27327476 : }
64 :
65 : // Logging can use Memory::Alloc, so we can't use logging with our
66 : // VerifyOrDie bits here.
67 : #define VERIFY_POINTER(p) VerifyOrDieWithoutLogging((p) == nullptr || MemoryDebugCheckPointer((p)))
68 :
69 : #endif
70 :
71 123 : CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize)
72 : {
73 : // Logging can use Memory::Alloc, so we can't use logging with our
74 : // VerifyOrDie bits here.
75 : #ifndef NDEBUG
76 123 : VerifyOrDieWithoutLogging(memoryInitialized++ == 0);
77 : #endif
78 123 : return CHIP_NO_ERROR;
79 : }
80 :
81 122 : void MemoryAllocatorShutdown()
82 : {
83 : // Logging can use Memory::Alloc, so we can't use logging with our
84 : // VerifyOrDie bits here.
85 : #ifndef NDEBUG
86 122 : VerifyOrDieWithoutLogging(--memoryInitialized == 0);
87 : #endif
88 : #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
89 : dmalloc_shutdown();
90 : #endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
91 122 : }
92 :
93 13659423 : void * MemoryAlloc(size_t size)
94 : {
95 13659423 : VERIFY_INITIALIZED();
96 13659423 : return malloc(size);
97 : }
98 :
99 4315 : void * MemoryCalloc(size_t num, size_t size)
100 : {
101 4315 : VERIFY_INITIALIZED();
102 4315 : return calloc(num, size);
103 : }
104 :
105 1 : void * MemoryRealloc(void * p, size_t size)
106 : {
107 1 : VERIFY_INITIALIZED();
108 1 : VERIFY_POINTER(p);
109 1 : return realloc(p, size);
110 : }
111 :
112 13663737 : void MemoryFree(void * p)
113 : {
114 13663737 : VERIFY_INITIALIZED();
115 13663737 : VERIFY_POINTER(p);
116 13663737 : free(p);
117 13663737 : }
118 :
119 0 : bool MemoryInternalCheckPointer(const void * p, size_t min_size)
120 : {
121 : #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
122 : return CanCastTo<int>(min_size) && (p != nullptr) &&
123 : (dmalloc_verify_pnt(__FILE__, __LINE__, __func__, p, 1, static_cast<int>(min_size)) == MALLOC_VERIFY_NOERROR);
124 : #else // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
125 0 : return (p != nullptr);
126 : #endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC
127 : }
128 :
129 : } // namespace Platform
130 : } // namespace chip
131 :
132 : #endif // CHIP_CONFIG_MEMORY_MGMT_MALLOC
|