1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "chpp/memory.h" 18 19 #include <stdatomic.h> 20 #include <stddef.h> 21 #include <stdlib.h> 22 23 #ifdef CHPP_LINUX_MEMORY_DEBUG 24 #include "chpp/log.h" 25 #endif // CHPP_LINUX_MEMORY_DEBUG 26 #include "chpp/macros.h" 27 #include "chpp/platform/utils.h" 28 29 //! A header used to track the amount of allocated memory. 30 struct ChppAllocHeader { 31 size_t bytes; 32 }; 33 34 static atomic_size_t gTotalAllocBytes = 0; 35 36 void *chppMalloc(const size_t size) { 37 void *ptr = NULL; 38 if (size != 0) { 39 ptr = malloc(sizeof(struct ChppAllocHeader) + size); 40 41 if (ptr != NULL) { 42 struct ChppAllocHeader *header = (struct ChppAllocHeader *)ptr; 43 header->bytes = size; 44 header++; 45 ptr = header; 46 47 gTotalAllocBytes += size; 48 } 49 } 50 51 #ifdef CHPP_LINUX_MEMORY_DEBUG 52 CHPP_LOGI("%s: size %zu total (after malloc) %zu", __func__, size, 53 gTotalAllocBytes); 54 #endif // CHPP_LINUX_MEMORY_DEBUG 55 56 return ptr; 57 } 58 59 void chppFree(void *ptr) { 60 if (ptr != NULL) { 61 struct ChppAllocHeader *header = (struct ChppAllocHeader *)ptr; 62 header--; 63 size_t size = header->bytes; 64 gTotalAllocBytes -= size; 65 66 #ifdef CHPP_LINUX_MEMORY_DEBUG 67 CHPP_LOGI("%s: size %zu total (after free) %zu", __func__, size, 68 gTotalAllocBytes); 69 #endif // CHPP_LINUX_MEMORY_DEBUG 70 71 free(header); 72 } 73 } 74 75 void *chppRealloc(void *oldPtr, const size_t newSize, const size_t oldSize) { 76 UNUSED_VAR(oldSize); 77 void *ptr = NULL; 78 if (newSize != oldSize) { 79 struct ChppAllocHeader *oldHeader = (struct ChppAllocHeader *)oldPtr; 80 oldHeader--; 81 82 void *reallocPtr = 83 realloc(oldHeader, newSize + sizeof(struct ChppAllocHeader)); 84 if (reallocPtr != NULL) { 85 struct ChppAllocHeader *newHeader = (struct ChppAllocHeader *)reallocPtr; 86 newHeader->bytes = newSize; 87 newHeader++; 88 ptr = newHeader; 89 90 if (newSize > oldSize) { 91 gTotalAllocBytes += (newSize - oldSize); 92 } else { 93 gTotalAllocBytes -= (oldSize - newSize); 94 } 95 } 96 } 97 98 #ifdef CHPP_LINUX_MEMORY_DEBUG 99 CHPP_LOGI("%s: size %zu total (after realloc) %zu", __func__, newSize, 100 gTotalAllocBytes); 101 #endif // CHPP_LINUX_MEMORY_DEBUG 102 103 return ptr; 104 } 105 106 void chppClearTotalAllocBytes() { 107 gTotalAllocBytes = 0; 108 } 109 110 size_t chppGetTotalAllocBytes() { 111 return gTotalAllocBytes; 112 } 113