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 17271756 : 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 17271756 : VerifyOrDieWithoutLogging(memoryInitialized); 63 17271756 : } 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 108 : 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 108 : VerifyOrDieWithoutLogging(memoryInitialized++ == 0); 77 : #endif 78 108 : return CHIP_NO_ERROR; 79 : } 80 : 81 106 : 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 106 : VerifyOrDieWithoutLogging(--memoryInitialized == 0); 87 : #endif 88 : #if CHIP_CONFIG_MEMORY_DEBUG_DMALLOC 89 : dmalloc_shutdown(); 90 : #endif // CHIP_CONFIG_MEMORY_DEBUG_DMALLOC 91 106 : } 92 : 93 8632097 : void * MemoryAlloc(size_t size) 94 : { 95 8632097 : VERIFY_INITIALIZED(); 96 8632097 : return malloc(size); 97 : } 98 : 99 3781 : void * MemoryCalloc(size_t num, size_t size) 100 : { 101 3781 : VERIFY_INITIALIZED(); 102 3781 : 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 8635877 : void MemoryFree(void * p) 113 : { 114 8635877 : VERIFY_INITIALIZED(); 115 8635877 : VERIFY_POINTER(p); 116 8635877 : free(p); 117 8635877 : } 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