Home | History | Annotate | Download | only in src
      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