1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 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 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /*! \file oscl_mem_imp.cpp 19 \brief This file contains the implementation of advanced memory APIs 20 */ 21 22 #include "oscl_mem.h" 23 24 25 ////////////////////// 26 // OsclMem 27 ////////////////////// 28 29 30 OSCL_EXPORT_REF void OsclMem::Init() 31 { 32 #if(!OSCL_BYPASS_MEMMGT) 33 OsclMemGlobalAuditObject::createGlobalMemAuditObject(); 34 #endif 35 } 36 37 OSCL_EXPORT_REF void OsclMem::Cleanup() 38 { 39 #if(!OSCL_BYPASS_MEMMGT) 40 OsclMemGlobalAuditObject::deleteGlobalMemAuditObject(); 41 #endif 42 } 43 44 45 46 ////////////////////// 47 // OsclMemInit 48 ////////////////////// 49 50 OSCL_EXPORT_REF void OsclMemInit(OsclAuditCB & auditCB) 51 { 52 #if(!OSCL_BYPASS_MEMMGT) 53 auditCB.pStatsNode = NULL; 54 auditCB.pAudit = (OsclMemGlobalAuditObject::getGlobalMemAuditObject()); 55 #else 56 OSCL_UNUSED_ARG(auditCB); 57 #endif 58 } 59 60 #if(!OSCL_BYPASS_MEMMGT) 61 62 #include "oscl_mem_audit.h" 63 64 #include "oscl_singleton.h" 65 66 ////////////////////// 67 // OsclMemGlobalAuditObject 68 ////////////////////// 69 70 OSCL_EXPORT_REF OsclMemGlobalAuditObject::audit_type* OsclMemGlobalAuditObject::getGlobalMemAuditObject() 71 { 72 return (audit_type*)OsclSingletonRegistryEx::getInstance(OSCL_SINGLETON_ID_OSCLMEM); 73 } 74 75 void OsclMemGlobalAuditObject::createGlobalMemAuditObject() 76 { 77 audit_type* audit = (audit_type*)OsclSingletonRegistryEx::lockAndGetInstance(OSCL_SINGLETON_ID_OSCLMEM); 78 if (audit) 79 { 80 audit->iRefCount++; 81 } 82 else 83 { 84 OsclAny *ptr = _oscl_malloc(sizeof(audit_type)); 85 if (!ptr) 86 { 87 OsclSingletonRegistryEx::registerInstanceAndUnlock(audit, OSCL_SINGLETON_ID_OSCLMEM); 88 OsclError::Leave(OsclErrNoMemory); 89 return; 90 } 91 audit = OSCL_PLACEMENT_NEW(ptr, audit_type()); 92 } 93 OsclSingletonRegistryEx::registerInstanceAndUnlock(audit, OSCL_SINGLETON_ID_OSCLMEM); 94 } 95 96 void OsclMemGlobalAuditObject::deleteGlobalMemAuditObject() 97 { 98 audit_type* audit = (audit_type*)OsclSingletonRegistryEx::lockAndGetInstance(OSCL_SINGLETON_ID_OSCLMEM); 99 if (!audit) 100 { 101 OsclSingletonRegistryEx::registerInstanceAndUnlock(audit, OSCL_SINGLETON_ID_OSCLMEM); 102 OsclError::Leave(OsclErrNotInstalled); 103 return; 104 } 105 audit->iRefCount--; 106 if (audit->iRefCount == 0) 107 { 108 audit->~OsclMemAudit(); 109 _oscl_free(audit); 110 audit = NULL; 111 } 112 OsclSingletonRegistryEx::registerInstanceAndUnlock(audit, OSCL_SINGLETON_ID_OSCLMEM); 113 } 114 115 ////////////////////// 116 // Default new/malloc 117 ////////////////////// 118 OSCL_EXPORT_REF void* _oscl_default_audit_new(size_t nBytes, const char * file_name, const int line_num) 119 { 120 //get global mem audit object. 121 OsclAuditCB audit; 122 OsclMemInit(audit); 123 return _oscl_audit_new(nBytes, audit, file_name, line_num); 124 } 125 126 OSCL_EXPORT_REF void* _oscl_default_audit_malloc(size_t nBytes, const char * file_name, const int line_num) 127 { 128 //get global mem audit object. 129 OsclAuditCB audit; 130 OsclMemInit(audit); 131 return _oscl_audit_malloc(nBytes, audit, file_name, line_num); 132 } 133 134 135 OSCL_EXPORT_REF void* _oscl_default_audit_calloc(size_t num, size_t nBytes, const char * file_name, const int line_num) 136 { 137 //get global mem audit object. 138 OsclAuditCB audit; 139 OsclMemInit(audit); 140 return _oscl_audit_calloc(num, nBytes, audit, file_name, line_num); 141 } 142 143 OSCL_EXPORT_REF void* _oscl_default_audit_realloc(void* in_ptr, size_t nBytes, const char * file_name, const int line_num) 144 { 145 //get global mem audit object. 146 OsclAuditCB audit; 147 OsclMemInit(audit); 148 return _oscl_audit_realloc(in_ptr, nBytes, audit, file_name, line_num); 149 } 150 151 ////////////////////// 152 // Audit new/malloc 153 ////////////////////// 154 155 OSCL_EXPORT_REF void* _oscl_audit_new(size_t nBytes, OsclAuditCB & auditCB, const char * file_name, const int line_num) 156 { 157 void * pTmp = auditCB.pAudit->MM_allocate(auditCB.pStatsNode, nBytes, file_name, line_num); 158 if (!pTmp) 159 OsclError::LeaveIfNull(pTmp); 160 return pTmp; 161 } 162 163 OSCL_EXPORT_REF void* _oscl_audit_malloc(size_t nBytes, OsclAuditCB & auditCB, const char * file_name, const int line_num) 164 { 165 return auditCB.pAudit->MM_allocate(auditCB.pStatsNode, nBytes, file_name, line_num); 166 } 167 168 OSCL_EXPORT_REF void* _oscl_audit_calloc(size_t num, size_t nBytes, OsclAuditCB & auditCB, const char * file_name, const int line_num) 169 { 170 size_t size = num * nBytes; 171 void* ptr = _oscl_audit_malloc(size, auditCB, file_name, line_num); 172 if (ptr) 173 oscl_memset(ptr, 0, size); 174 //note: return pointer can be null. 175 return ptr; 176 } 177 178 OSCL_EXPORT_REF void* _oscl_audit_realloc(void* in_ptr, size_t nBytes, OsclAuditCB & auditCB, const char * file_name, const int line_num) 179 { 180 if (nBytes > 0) 181 { 182 //allocate new space 183 void* ptr = _oscl_audit_malloc(nBytes, auditCB, file_name, line_num); 184 if (in_ptr && ptr) 185 { 186 //copy current contents to new space. 187 //note: the getSize call leaves if it's a bad pointer. 188 //just propagate the leave to the caller. 189 if (MM_Audit_Imp::getSize(in_ptr) > MM_Audit_Imp::getSize(ptr)) 190 { 191 oscl_memcpy(ptr, in_ptr, MM_Audit_Imp::getSize(ptr)); 192 } 193 else 194 { 195 oscl_memcpy(ptr, in_ptr, MM_Audit_Imp::getSize(in_ptr)); 196 } 197 //free original space. 198 _oscl_audit_free(in_ptr); 199 } 200 else if (in_ptr) 201 { 202 return in_ptr; 203 } 204 //note: return pointer can be null. 205 return ptr; 206 } 207 else 208 { 209 _oscl_audit_free(in_ptr); 210 return NULL; 211 } 212 } 213 214 ////////////// 215 // Free 216 ////////////// 217 OSCL_EXPORT_REF void _oscl_audit_free(void *p) 218 { 219 //always free from the root node-- global audit object. 220 //Get the audit root from within the alloc block rather 221 //than from TLS, since we can't be sure this call is 222 //in the same thread as the allocation. 223 OsclMemAudit *pAuditRoot = MM_Audit_Imp::getAuditRoot(p) ; 224 if (pAuditRoot) 225 { 226 pAuditRoot->MM_deallocate(p); 227 } 228 else 229 {//bad or corrupt block? 230 OSCL_LEAVE(OsclErrArgument); 231 } 232 } 233 234 #else 235 236 OSCL_EXPORT_REF void* _oscl_default_new(size_t nBytes) 237 { 238 void * pTmp = _oscl_malloc(nBytes); 239 if (!pTmp) 240 OsclError::LeaveIfNull(pTmp); 241 return pTmp; 242 } 243 244 #endif //OSCL_BYPASS_MEMMGT 245 246 247