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 // -*- c++ -*-
     19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     20 
     21 //                  O S C L _ M E M
     22 
     23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     24 
     25 /*! \addtogroup osclmemory OSCL Memory
     26  *
     27  * @{
     28  */
     29 
     30 
     31 /*! \file oscl_mem.h
     32     \brief This file contains basic memory definitions for common use across platforms.
     33 
     34     This is the main entry point header file for the OSCL memory library.  It should be
     35     the only one users directly include.  Basic memory copy, compare, and move functions
     36     are defined here as well as the allocation functions.
     37 */
     38 
     39 #ifndef OSCL_MEM_H_INCLUDED
     40 #define OSCL_MEM_H_INCLUDED
     41 
     42 #ifndef OSCLCONFIG_MEMORY_H_INCLUDED
     43 #include "osclconfig_memory.h"
     44 #endif
     45 
     46 #ifndef OSCL_BASE_H_INCLUDED
     47 #include "oscl_base.h"
     48 #endif
     49 
     50 #ifndef OSCL_TYPES_H_INCLUDE
     51 #include "oscl_types.h"
     52 #endif
     53 
     54 #ifndef OSCL_ASSERT_H_INCLUDED
     55 #include "oscl_assert.h"
     56 #endif
     57 
     58 #ifndef OSCL_MEM_BASIC_FUNCTIONS_H
     59 #include "oscl_mem_basic_functions.h"
     60 #endif
     61 
     62 #ifndef OSCL_LOCK_BASE_H_INCLUDED
     63 #include "oscl_lock_base.h"
     64 #endif
     65 
     66 #define OSCL_DISABLE_WARNING_TRUNCATE_DEBUG_MESSAGE
     67 #include "osclconfig_compiler_warnings.h"
     68 
     69 #ifndef OSCL_MEM_INST_H_INCLUDED
     70 #include "oscl_mem_inst.h"
     71 #endif
     72 
     73 #ifndef OSCL_HEAPBASE_H_INCLUDED
     74 #include "oscl_heapbase.h"
     75 #endif
     76 
     77 //Default for OSCL_HAS_GLOBAL_NEW_DELETE in case it is *not* defined
     78 //in the osclconfig_memory.h
     79 #ifndef OSCL_HAS_GLOBAL_NEW_DELETE
     80 #ifdef NDEBUG
     81 //Release Mode - No definition for global new and delete.
     82 #define OSCL_HAS_GLOBAL_NEW_DELETE 0
     83 #else
     84 //Debug Mode - Define global new and delete.
     85 #define OSCL_HAS_GLOBAL_NEW_DELETE 1
     86 #endif //NDEBUG
     87 #endif //OSCL_HAS_GLOBAL_NEW_DELETE
     88 
     89 class OsclMem
     90 {
     91     public:
     92         /** Per-thread initialization of Oscl Memory
     93         **   @param lock: A lock class for use with multi-threaded applications.
     94         **      The lock is needed in use cases where memory may be allocated
     95         **      in one thread and freed in another.  In this case, there must
     96         **      be a single lock object, and its pointer must be passed to
     97         **      the OsclMem::Init call in each thread.
     98         **      If no lock is provided, the memory manager will not be thread-safe.
     99         ** @exception: Leaves on error
    100         */
    101         OSCL_IMPORT_REF static void Init();
    102 
    103         /** Per-thread cleanup of Oscl Memory
    104         ** @exception: Leaves on error;
    105         */
    106         OSCL_IMPORT_REF static void Cleanup();
    107 
    108 };
    109 
    110 /*
    111 ** Choose whether to use per-thread or singleton registry for auditing
    112 */
    113 #include "oscl_base.h"
    114 
    115 /*
    116 ** Audit control block
    117 */
    118 #if (OSCL_BYPASS_MEMMGT)
    119 //empty class for compilation only
    120 class OsclAuditCB
    121 {
    122     public:
    123 };
    124 #else
    125 class OsclMemStatsNode;
    126 class OsclMemAudit;
    127 class OsclAuditCB
    128 {
    129     public:
    130         const OsclMemStatsNode* pStatsNode;
    131         OsclMemAudit *pAudit;
    132 
    133         OsclAuditCB() :
    134                 pStatsNode(NULL),
    135                 pAudit(NULL)
    136         {}
    137 
    138         OsclAuditCB(const OsclMemStatsNode* myStatsNode,
    139                     OsclMemAudit *ptr)
    140                 :
    141                 pStatsNode(myStatsNode),
    142                 pAudit(ptr)
    143         {
    144         }
    145 };
    146 #endif//OSCL_BYPASS_MEMMGT
    147 
    148 /**
    149  * Get memory-aligned size of an object.
    150  *
    151  * @param size size of object
    152  *
    153  * @returns memory-aligned size
    154  */
    155 OSCL_COND_IMPORT_REF uint oscl_mem_aligned_size(uint size);
    156 
    157 /**
    158  * Initialize an OsclAuditCB object.
    159  * Sets the stats node pointer to null, and sets the
    160  * audit pointer to the global audit object.
    161  *
    162  * @param auditCB memory management audit object
    163  */
    164 OSCL_IMPORT_REF void OsclMemInit(OsclAuditCB & auditCB);
    165 
    166 /**
    167  * Cleans up the base class of a partially-constructed
    168  * derived class.  This macro will call the destructor
    169  * if necessary, based on the error-handling implementation.
    170  *
    171  * @param T: name of the base class.
    172  */
    173 #define OSCL_CLEANUP_BASE_CLASS(T) _OSCL_CLEANUP_BASE_CLASS(T)
    174 
    175 /** *******************************************************
    176  * Macros for new/delete with a given allocator/deallocator.
    177  */
    178 
    179 /**
    180  * Creates an object of type T using the given allocator to
    181  * acquire the memory needed.
    182  *
    183  * @param T_allocator allocator for objects of type T, must be
    184  *    an Oscl_TAlloc<T, Allocator>, where Allocator is an Oscl_DefAlloc
    185  * @param T           type of object to create
    186  * @param params      object initialization parameters
    187  *
    188  * @return pointer to created object
    189  *
    190  * @exception none, unless thrown by the given allocator
    191  */
    192 #if(OSCL_BYPASS_MEMMGT)
    193 #define OSCL_ALLOC_NEW(T_allocator, T, params) new(T_allocator.allocate(1)) T params
    194 #elif(PVMEM_INST_LEVEL>0)
    195 #define OSCL_ALLOC_NEW(T_allocator, T, params) new(T_allocator.allocate_fl(1,__FILE__,__LINE__)) T params
    196 #else
    197 #define OSCL_ALLOC_NEW(T_allocator, T, params) new(T_allocator.allocate(1)) T params
    198 #endif
    199 
    200 /**
    201  * Creates an object of type T using the given allocator to
    202  * acquire the memory needed.
    203  * This macro is similar to OSCL_ALLOC_NEW except that it
    204  * handles constructors that leave.
    205  * If the constructor leaves, the destructor will be called,
    206  * and allocated memory will be freed before allowing the
    207  * leave to propagate to the next level.
    208  *
    209  * @param T_ptr    variable to hold return value-- pointer to
    210  *                 new object of type T.
    211  * @param T_allocator allocator for objects of type T, must be
    212  *    an Oscl_TAlloc<T, Allocator>, where Allocator is an
    213  *    Oscl_DefAlloc
    214  * @param T        type of object to create
    215  * @param params   object initialization parameters
    216  *
    217  * @return pointer to created object
    218  *
    219  * @exception none, unless thrown by the given allocator
    220  */
    221 #if(OSCL_BYPASS_MEMMGT)
    222 #define OSCL_TRAP_ALLOC_NEW(T_ptr,T_allocator,T,params) _OSCL_TRAP_NEW(T_allocator.allocate(1),T_allocator.deallocate,T_ptr,T,params)
    223 #elif(PVMEM_INST_LEVEL>0)
    224 #define OSCL_TRAP_ALLOC_NEW(T_ptr,T_allocator,T,params) _OSCL_TRAP_NEW(T_allocator.allocate_fl(1,__FILE__,__LINE__),T_allocator.deallocate,T_ptr,T,params)
    225 #else
    226 #define OSCL_TRAP_ALLOC_NEW(T_ptr,T_allocator,T,params) _OSCL_TRAP_NEW(T_allocator.allocate(1),T_allocator.deallocate,T_ptr,T,params)
    227 #endif
    228 
    229 /**
    230  * Deletes the object of type T using the given allocator
    231  *
    232  * @param T_allocator allocator for objects of type T
    233  * @param T           type of object to delete
    234  * @param ptr         pointer to previously created object
    235  *
    236  * @exception none, unless thrown by the given allocator
    237  */
    238 #define OSCL_ALLOC_DELETE(ptr, T_allocator, T) \
    239   {\
    240   ptr->~T();\
    241   T_allocator.deallocate(ptr);\
    242   }
    243 
    244 
    245 /** *******************************************************
    246  * Macros for malloc/free with memory management.
    247  */
    248 
    249 //These are for internal use but need to be visible since they're used
    250 //in macros.
    251 #if(!OSCL_BYPASS_MEMMGT)
    252 OSCL_IMPORT_REF void* _oscl_audit_malloc(size_t , OsclAuditCB & , const char * f = NULL, const int l = 0);
    253 OSCL_IMPORT_REF void* _oscl_audit_calloc(size_t , size_t, OsclAuditCB & , const char * f = NULL, const int l = 0);
    254 OSCL_IMPORT_REF void* _oscl_audit_realloc(void*, size_t , OsclAuditCB & , const char * f = NULL, const int l = 0);
    255 OSCL_IMPORT_REF void* _oscl_audit_new(size_t , OsclAuditCB & , const char * f = NULL, const int l = 0) ;
    256 OSCL_IMPORT_REF void* _oscl_default_audit_malloc(size_t , const char * f = NULL, const int l = 0);
    257 OSCL_IMPORT_REF void* _oscl_default_audit_calloc(size_t , size_t, const char * f = NULL, const int l = 0);
    258 OSCL_IMPORT_REF void* _oscl_default_audit_realloc(void*, size_t , const char * f = NULL, const int l = 0);
    259 OSCL_IMPORT_REF void* _oscl_default_audit_new(size_t , const char * f = NULL, const int l = 0) ;
    260 OSCL_IMPORT_REF void _oscl_audit_free(void *);
    261 #else
    262 OSCL_IMPORT_REF void* _oscl_default_new(size_t nBytes);
    263 #endif//OSCL_BYPASS_MEMMGT
    264 
    265 #if (OSCL_HAS_GLOBAL_NEW_DELETE)
    266 //Global New operator overloaded to check native new operators called
    267 
    268 #if(!OSCL_BYPASS_MEMMGT)
    269 inline void * operator new(size_t aSize, const char *aFile, int aLine)
    270 {
    271 #if(PVMEM_INST_LEVEL>0)
    272     //in case NULL is passed in, record this file & line #
    273     if (!aFile)
    274         return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    275 #endif
    276     return _oscl_default_audit_new(aSize, aFile, aLine);
    277 };
    278 #endif
    279 
    280 #if(!OSCL_BYPASS_MEMMGT)
    281 inline void * operator new(size_t aSize)
    282 {
    283 #if(PVMEM_INST_LEVEL>0)
    284     return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    285 #else
    286     return _oscl_default_audit_new(aSize);
    287 #endif
    288 };
    289 #endif
    290 
    291 #if(!OSCL_BYPASS_MEMMGT)
    292 inline void operator delete(void *aPtr)
    293 {
    294     _oscl_audit_free(aPtr);
    295 };
    296 #endif
    297 
    298 #if(!OSCL_BYPASS_MEMMGT)
    299 inline void * operator new[](size_t aSize, const char *aFile, int aLine)
    300 {
    301 #if(PVMEM_INST_LEVEL>0)
    302     //in case NULL is passed in, record this file & line #
    303     if (!aFile)
    304         return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    305 #endif
    306     return _oscl_default_audit_new(aSize, aFile, aLine);
    307 };
    308 #endif
    309 
    310 #if(!OSCL_BYPASS_MEMMGT)
    311 inline void * operator new[](size_t aSize)
    312 {
    313 #if(PVMEM_INST_LEVEL>0)
    314     return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    315 #else
    316     return _oscl_default_audit_new(aSize);
    317 #endif
    318 };
    319 #endif
    320 
    321 #if(!OSCL_BYPASS_MEMMGT)
    322 inline void operator delete[](void *aPtr)
    323 {
    324     _oscl_audit_free(aPtr);
    325 };
    326 #endif
    327 #endif //OSCL_HAS_GLOBAL_NEW_DELETE
    328 
    329 /**
    330  * Allocates a memory block using the memory management's
    331  * global audit object.
    332  *
    333  * @param count  number of bytes to allocate
    334  *
    335  * @return a void pointer to the allocated space, or NULL if there is insufficient
    336  *         memory available.
    337  *
    338  * @exception none
    339  */
    340 #if(OSCL_BYPASS_MEMMGT)
    341 #define OSCL_MALLOC(count) _oscl_malloc(count)
    342 #elif(PVMEM_INST_LEVEL>0)
    343 #define OSCL_MALLOC(count) _oscl_default_audit_malloc(count,__FILE__,__LINE__)
    344 #else
    345 #define OSCL_MALLOC(count) _oscl_default_audit_malloc(count)
    346 #endif
    347 
    348 /*
    349 ** The public oscl_malloc call has been deprecated.
    350 ** PV code should call OSCL_MALLOC.
    351 ** This macro is defined for back-compatibility.
    352 */
    353 #define oscl_malloc(a) OSCL_MALLOC(a)
    354 
    355 /**
    356  * Another back-compatibility definition.
    357  */
    358 #define OSCL_DEFAULT_MALLOC(x) OSCL_MALLOC(x)
    359 
    360 /**
    361 * Allocates a memory block using the given audit object.
    362 *
    363 * @param auditCB input memory management audit object
    364 * @param count   number of bytes to allocate
    365 *
    366 * @return a void pointer to the allocated space, or NULL if there is insufficient
    367 *         memory available.
    368 *
    369 * @exception none
    370 */
    371 #if(OSCL_BYPASS_MEMMGT)
    372 #define OSCL_AUDIT_MALLOC(auditCB, count) _oscl_malloc(count)
    373 #elif(PVMEM_INST_LEVEL>0)
    374 #define OSCL_AUDIT_MALLOC(auditCB, count) _oscl_audit_malloc(count, auditCB, __FILE__, __LINE__)
    375 #else
    376 #define OSCL_AUDIT_MALLOC(auditCB, count) _oscl_audit_malloc(count, auditCB)
    377 #endif
    378 
    379 /**
    380  * Allocates a memory block using the memory management's
    381  * global audit object.  The block is initialized to zero.
    382  *
    383  * @param num  number of elements
    384  * @param size  number of bytes to allocate for each element
    385  *
    386  * @return a void pointer to the allocated space, or NULL if there is insufficient
    387  *         memory available.
    388  *
    389  * @exception none
    390  */
    391 #if(OSCL_BYPASS_MEMMGT)
    392 #define OSCL_CALLOC(num,size) _oscl_calloc(num,size)
    393 #elif(PVMEM_INST_LEVEL>0)
    394 #define OSCL_CALLOC(num,size) _oscl_default_audit_calloc(num,size,__FILE__,__LINE__)
    395 #else
    396 #define OSCL_CALLOC(num,size) _oscl_default_audit_calloc(num,size)
    397 #endif
    398 
    399 /*
    400 ** The public oscl_calloc call has been deprecated.
    401 ** PV code should call OSCL_CALLOC.
    402 ** This macro is defined for back-compatibility.
    403 */
    404 #define oscl_calloc(a,b) OSCL_CALLOC(a,b)
    405 
    406 /**
    407 * Allocates a memory block using the specified
    408 * audit object.  The block is initialized to zero.
    409 *
    410 * @param auditCB input memory management audit object
    411 * @param num  number of elements
    412 * @param size  number of bytes to allocate for each element
    413 *
    414 * @return a void pointer to the allocated space, or NULL if there is insufficient
    415 *         memory available.
    416 *
    417 * @exception none
    418 */
    419 #if(OSCL_BYPASS_MEMMGT)
    420 #define OSCL_AUDIT_CALLOC(auditCB, num,size) _oscl_calloc(num,size)
    421 #elif(PVMEM_INST_LEVEL>0)
    422 #define OSCL_AUDIT_CALLOC(auditCB, num,size) _oscl_audit_calloc(num,size, auditCB, __FILE__, __LINE__)
    423 #else
    424 #define OSCL_AUDIT_CALLOC(auditCB, num,size) _oscl_audit_calloc(num,size, auditCB)
    425 #endif
    426 
    427 /**
    428  * Re-Allocates a memory block using the memory management's
    429  * global audit object.
    430  *
    431  * @param ptr  original memory block
    432  * @param new_size  New size of the block
    433  *
    434  * @return a void pointer to the allocated space, or NULL if there is insufficient
    435  *         memory available.
    436  *
    437  * @exception none
    438  */
    439 #if(OSCL_BYPASS_MEMMGT)
    440 #define OSCL_REALLOC(ptr,new_size) _oscl_realloc(ptr,new_size)
    441 #elif(PVMEM_INST_LEVEL>0)
    442 #define OSCL_REALLOC(ptr,new_size) _oscl_default_audit_realloc(ptr,new_size,__FILE__,__LINE__)
    443 #else
    444 #define OSCL_REALLOC(ptr,new_size) _oscl_default_audit_realloc(ptr,new_size)
    445 #endif
    446 
    447 /*
    448 ** The public oscl_realloc call has been deprecated.
    449 ** PV code should call OSCL_REALLOC.  This macro is
    450 ** defined for back-compatibility.
    451 */
    452 #define oscl_realloc(a,b) OSCL_REALLOC(a,b)
    453 
    454 /**
    455 * Re-Allocates a memory block using the specified
    456 * audit object.
    457 *
    458 * @param auditCB input memory management audit object
    459 * @param ptr  original memory block
    460 * @param new_size  New size of the block
    461 *
    462 * @return a void pointer to the allocated space, or NULL if there is insufficient
    463 *         memory available.
    464 *
    465 * @exception none
    466 */
    467 #if(OSCL_BYPASS_MEMMGT)
    468 #define OSCL_AUDIT_REALLOC(auditCB, ptr,new_size) _oscl_realloc(ptr,new_size)
    469 #elif(PVMEM_INST_LEVEL>0)
    470 #define OSCL_AUDIT_REALLOC(auditCB, ptr,new_size) _oscl_audit_realloc(ptr,new_size, auditCB, __FILE__, __LINE__)
    471 #else
    472 #define OSCL_AUDIT_REALLOC(auditCB, ptr,new_size) _oscl_audit_realloc(ptr,new_size, auditCB)
    473 #endif
    474 
    475 /**
    476  * Deallocates or frees a memory block.
    477  *
    478  * @param ptr    pointer to previously allocated memory block using the given audit object
    479  */
    480 #if(OSCL_BYPASS_MEMMGT)
    481 #define OSCL_FREE(ptr) _oscl_free(ptr)
    482 #else
    483 #define OSCL_FREE(ptr) _oscl_audit_free(ptr)
    484 #endif
    485 
    486 /*
    487 ** The public oscl_free call has been deprecated.
    488 ** PV code should call OSCL_FREE.
    489 ** This macro is defined for back-compatibility.
    490 */
    491 #define oscl_free(x) OSCL_FREE(x)
    492 
    493 /**
    494  * Another back-compatibility definition.
    495  */
    496 #define OSCL_DEFAULT_FREE(x) OSCL_FREE(x)
    497 
    498 /** *******************************************************
    499  * Macros for new/delete with memory management.
    500  */
    501 
    502 /**
    503  * Oscl "new" operator.  This uses the global memory
    504  * audit object.
    505  *
    506  * @param T       data type for 'new' operation
    507  * @param params  object initialization parameters
    508  *
    509  * @return pointer to the newly created object of type T
    510  *
    511  * @exception may leave with code = bad alloc
    512  *
    513  *
    514  */
    515 #if(OSCL_BYPASS_MEMMGT)
    516 #define OSCL_NEW( T, params) new T params
    517 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    518 #define OSCL_NEW( T, params) new T params
    519 #elif(PVMEM_INST_LEVEL>0)
    520 #define OSCL_NEW( T, params) new(__FILE__,__LINE__) T params
    521 #else
    522 #define OSCL_NEW( T, params) new T params
    523 #endif
    524 
    525 /********************************************************
    526  * Macro for placement new
    527  *
    528  * @param ptr          pointer to an object
    529  *
    530  * @param constructor  constructor of the class for the object
    531  *
    532 ********************************************************/
    533 #define OSCL_PLACEMENT_NEW(ptr, constructor) new(ptr) constructor
    534 
    535 /**
    536  * Oscl "new" operator.  This uses the global memory
    537  * audit object.  This operator is similar to OSCL_NEW
    538  * except that it will handle constructors that leave.
    539  * If the constructor leaves, the destructor will be called,
    540  * and allocated memory will be freed before allowing the
    541  * leave to propagate to the next level.
    542  *
    543  * @param T_ptr   variable to hold return value-- pointer to
    544  *                new object of type T.
    545  * @param T       data type for 'new' operation
    546  * @param params  object initialization parameters
    547  *
    548  * @return pointer to the newly created object of type T
    549  *
    550  * @exception may leave with code = bad alloc
    551  *
    552  *
    553  */
    554 #if(OSCL_BYPASS_MEMMGT)
    555 #define OSCL_TRAP_NEW(T_ptr,T,params) _OSCL_TRAP_NEW(_oscl_default_new(sizeof(T)),_oscl_free,T_ptr,T,params)
    556 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    557 #define OSCL_TRAP_NEW(T_ptr,T,params) _OSCL_TRAP_NEW(_oscl_default_audit_new(sizeof(T)),_oscl_audit_free,T_ptr,T,params)
    558 #elif(PVMEM_INST_LEVEL>0)
    559 #define OSCL_TRAP_NEW(T_ptr,T,params) _OSCL_TRAP_NEW(_oscl_default_audit_new(sizeof(T),__FILE__,__LINE__),_oscl_audit_free,T_ptr,T,params)
    560 #else
    561 #define OSCL_TRAP_NEW(T_ptr,T,params) _OSCL_TRAP_NEW(_oscl_default_audit_new(sizeof(T)),_oscl_audit_free,T_ptr,T,params)
    562 #endif
    563 
    564 
    565 /**
    566  * Oscl "new" operator.  This uses the specified memory
    567  * audit object.
    568  *
    569  * @param auditCB input memory management audit object
    570  * @param T       data type for 'new' operation
    571  * @param params  object initialization parameters
    572  *
    573  * @return pointer to the newly created object of type T
    574  *
    575  * @exception may leave with code = bad alloc
    576  *
    577  */
    578 #if(OSCL_BYPASS_MEMMGT)
    579 #define OSCL_AUDIT_NEW(auditCB, T, params) new(_oscl_default_new(sizeof(T))) T params
    580 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    581 #define OSCL_AUDIT_NEW(auditCB, T, params) new(_oscl_audit_new(sizeof(T),auditCB)) T params
    582 #elif(PVMEM_INST_LEVEL>0)
    583 #define OSCL_AUDIT_NEW(auditCB, T, params) new(_oscl_audit_new(sizeof(T),auditCB,__FILE__,__LINE__)) T params
    584 #else
    585 #define OSCL_AUDIT_NEW(auditCB, T, params) new(_oscl_audit_new(sizeof(T),auditCB)) T params
    586 #endif
    587 
    588 /**
    589  * Oscl "new" operator.  This uses the specified memory
    590  * audit object.  This macro is similar to OSCL_AUDIT_NEW
    591  * except that it will handle constructors that leave.
    592  * If the constructor leaves, the destructor will be called,
    593  * and allocated memory will be freed before allowing the
    594  * leave to propagate to the next level.
    595  *
    596  * @param T_ptr   variable to hold return value-- pointer to
    597  *                new object of type T.
    598  * @param auditCB input memory management audit object
    599  * @param T       data type for 'new' operation
    600  * @param params  object initialization parameters
    601  *
    602  * @return pointer to the newly created object of type T
    603  *
    604  * @exception may leave with code = bad alloc
    605  *
    606  */
    607 #if(OSCL_BYPASS_MEMMGT)
    608 #define OSCL_TRAP_AUDIT_NEW(T_ptr,auditCB,T,params) _OSCL_TRAP_NEW(_oscl_default_new(sizeof(T)),_oscl_free,T_ptr,T,params)
    609 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    610 #define OSCL_TRAP_AUDIT_NEW(T_ptr,auditCB,T,params) _OSCL_TRAP_NEW(_oscl_audit_new(sizeof(T),auditCB),_oscl_audit_free,T_ptr,T,params)
    611 #elif(PVMEM_INST_LEVEL>0)
    612 #define OSCL_TRAP_AUDIT_NEW(T_ptr,auditCB,T,params) _OSCL_TRAP_NEW(_oscl_audit_new(sizeof(T),auditCB,__FILE__,__LINE__),_oscl_audit_free,T_ptr,T,params)
    613 #else
    614 #define OSCL_TRAP_AUDIT_NEW(T_ptr,auditCB,T,params) _OSCL_TRAP_NEW(_oscl_audit_new(sizeof(T),auditCB),_oscl_audit_free,T_ptr,T,params)
    615 #endif
    616 
    617 /**
    618  * Oscl "delete" operator.
    619  *
    620  * @param ptr pointer to memory block previously allocated with OSCL_NEW
    621  *
    622  * @return void
    623  */
    624 #define OSCL_DELETE(ptr) {\
    625     if(ptr){delete(ptr);}\
    626 }
    627 
    628 
    629 /** *******************************************************
    630  * Macros for array new/delete with memory management.
    631  * These only work for simple array types and cannot
    632  * be used for class types with constructor/destructors.
    633  *
    634  * Note: some compilers do not support placement array
    635  * new operator, so these macros don't use it.
    636  */
    637 
    638 /**
    639  * Oscl array "new" operator.  This uses the input memory
    640  * audit object.
    641  *
    642  * @param auditCB input memory management audit object
    643  * @param T       data type for 'new' operation
    644  * @param count   number of elements to create
    645  *
    646  * @return pointer to the newly created object array of type T
    647  *
    648  * @exception may leave with code = bad alloc
    649  *
    650  *
    651  */
    652 #if(OSCL_BYPASS_MEMMGT)
    653 #define OSCL_AUDIT_ARRAY_NEW(auditCB, T, count) new(_oscl_default_new(sizeof(T)*(count))) T
    654 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    655 #define OSCL_AUDIT_ARRAY_NEW(auditCB, T, count) new(_oscl_audit_new(sizeof(T)*(count),auditCB)) T
    656 #elif(PVMEM_INST_LEVEL>0)
    657 #define OSCL_AUDIT_ARRAY_NEW(auditCB, T, count) new(_oscl_audit_new(sizeof(T)*(count),auditCB,__FILE__,__LINE__)) T
    658 #else
    659 #define OSCL_AUDIT_ARRAY_NEW(auditCB, T, count) new(_oscl_audit_new(sizeof(T)*(count),auditCB)) T
    660 #endif
    661 
    662 /**
    663  * Oscl array "new" operator.  This uses the global memory
    664  * audit object.
    665  *
    666  * @param T       data type for 'new' operation
    667  * @param count   number of elements to create
    668  *
    669  * @return pointer to the newly created object array of type T
    670  *
    671  * @exception may leave with code = bad alloc
    672  *
    673  *
    674  */
    675 #if(OSCL_BYPASS_MEMMGT)
    676 #define OSCL_ARRAY_NEW(T, count) new T[count]
    677 #elif!(OSCL_HAS_GLOBAL_NEW_DELETE)
    678 #define OSCL_ARRAY_NEW(T, count) new T[count]
    679 #elif(PVMEM_INST_LEVEL>0)
    680 #define OSCL_ARRAY_NEW(T, count) new(__FILE__,__LINE__) T[count]
    681 #else
    682 #define OSCL_ARRAY_NEW(T, count) new T[count]
    683 #endif
    684 
    685 /**
    686  * Oscl array delete operator..
    687  *
    688  * @param ptr pointer to memory block previously allocated with OSCL_ARRAY_NEW
    689  *
    690  * @return void
    691  */
    692 #define OSCL_ARRAY_DELETE(ptr) delete [] ptr
    693 
    694 
    695 /**
    696 * Previously this was in oscl_mem_imp.h
    697 */
    698 
    699 #ifndef OSCL_DEFALLOC_H_INCLUDED
    700 #include "oscl_defalloc.h"
    701 #endif
    702 
    703 #ifndef OSCL_REFCOUNTER_H_INCLUDED
    704 #include "oscl_refcounter.h"
    705 #endif
    706 
    707 #ifndef OSCL_MEM_BASIC_FUNCTIONS_H_INCLUDED
    708 #include "oscl_mem_basic_functions.h"
    709 #endif
    710 
    711 #ifndef OSCL_ERROR_H_INCLUDED
    712 #include "oscl_error.h"
    713 #endif
    714 
    715 #ifndef OSCL_EXCEPTION_H_INCLUDED
    716 #include "oscl_exception.h"
    717 #endif
    718 
    719 #define OSCL_DISABLE_WARNING_TRUNCATE_DEBUG_MESSAGE
    720 #include "osclconfig_compiler_warnings.h"
    721 
    722 /** \class OsclMemAllocator
    723 ** A simple allocator class.  Configurable as to whether
    724 ** this goes through the memory manager or not.
    725 **
    726 */
    727 class OsclMemAllocator : public Oscl_DefAlloc
    728 {
    729     public:
    730         /** This API throws an exception when malloc returns NULL.
    731           * n must be greater than 0.
    732           *
    733           * @return pointer (or Leave with OsclErrNoMemory )
    734           *
    735           */
    736         OsclAny* allocate(const uint32 n)
    737         {
    738 #if(OSCL_BYPASS_MEMMGT)
    739             OsclAny* p = _oscl_malloc(n);
    740             if (!p)
    741                 OsclError::LeaveIfNull(p);
    742 #if OSCL_MEM_FILL_WITH_PATTERN
    743             oscl_memset(p, 0x55, n);
    744 #endif
    745             return (p);
    746 #elif (PVMEM_INST_LEVEL>0)
    747             //this is really a usage error-- caller should provide file & line.
    748             //set a debug breakpoint here...
    749             return allocate_fl(n, __FILE__, __LINE__);
    750 #else
    751             return allocate_fl(n, NULL, 0);
    752 #endif
    753         }
    754 
    755 #if(!OSCL_BYPASS_MEMMGT)
    756         OsclAny* allocate_fl(const uint32 n, const char * file_name, const int line_num)
    757         {
    758             OsclAny* p = _oscl_default_audit_malloc(n, file_name, line_num);
    759             if (!p)
    760                 OsclError::LeaveIfNull(p);
    761 #if OSCL_MEM_FILL_WITH_PATTERN
    762             oscl_memset(p, 0x55, n);
    763 #endif
    764             return (p);
    765         }
    766 #endif
    767 
    768         void deallocate(OsclAny* p)
    769         {
    770             if (p)
    771                 OSCL_FREE(p);
    772         }
    773 };
    774 
    775 
    776 /** \class OsclMemBasicAllocator
    777 ** A simple allocator class that does not use the memory management.
    778 **
    779 ** Note: this allocator is for internal use by Oscl only.  Higher
    780 ** level code should use OsclMemAllocator.
    781 **
    782 */
    783 class OsclMemBasicAllocator : public Oscl_DefAlloc
    784 {
    785     public:
    786         /** This API throws an exception when malloc returns NULL.
    787           * n must be greater than 0.
    788           *
    789           * @return pointer (or Leave with OsclErrNoMemory )
    790           *
    791           */
    792         OsclAny* allocate(const uint32 n)
    793         {
    794             OsclAny* p = _oscl_malloc(n);
    795             OsclError::LeaveIfNull(p);
    796 #if OSCL_MEM_FILL_WITH_PATTERN
    797             oscl_memset(p, 0x55, n);
    798 #endif
    799             return (p);
    800         }
    801 
    802         void deallocate(OsclAny* p)
    803         {
    804             if (p)
    805                 _oscl_free(p);
    806         }
    807 };
    808 
    809 /** \class OsclMemAllocDestructDealloc
    810 ** An OsclAllocDestructDealloc class that uses
    811 ** OsclMemAllocator.
    812 */
    813 template <class T> class OsclMemAllocDestructDealloc : public OsclAllocDestructDealloc
    814 {
    815     public:
    816 #if !(OSCL_BYPASS_MEMMGT)
    817         OsclAny* allocate_fl(const uint32 size, const char * file_name, const int line_num)
    818         {
    819             return alloc.allocate_fl(size, file_name, line_num);
    820         }
    821 #endif
    822         OsclAny* allocate(const uint32 size)
    823         {
    824 #if(OSCL_BYPASS_MEMMGT)
    825             return alloc.allocate(size);
    826 #elif(PVMEM_INST_LEVEL>0)
    827             //this is really a usage error-- caller should provide file & line.
    828             //set a debug breakpoint here...
    829             return allocate_fl(size, __FILE__, __LINE__);
    830 #else
    831             return allocate_fl(size, NULL, 0);
    832 #endif
    833         }
    834         void deallocate(OsclAny* p)
    835         {
    836             alloc.deallocate(p);
    837         }
    838         void destruct_and_dealloc(OsclAny* p)
    839         {
    840             T* ptr = reinterpret_cast<T*>(p);
    841             ptr->~T();
    842             deallocate(p);
    843             OSCL_UNUSED_ARG(ptr); // removes warning on some compilers
    844         }
    845     private:
    846         OsclMemAllocator alloc;
    847 };
    848 
    849 /** \class OsclMemBasicAllocDestructDealloc
    850 ** An OsclAllocDestructDealloc class that uses
    851 ** OsclMemBasicAllocator.
    852 */
    853 template <class T> class OsclMemBasicAllocDestructDealloc : public OsclAllocDestructDealloc
    854 {
    855     public:
    856         OsclAny* allocate(const uint32 size)
    857         {
    858 #if(OSCL_BYPASS_MEMMGT)
    859             return alloc.allocate(size);
    860 #else
    861             return alloc.allocate_fl(size, NULL, 0);
    862 #endif
    863         }
    864         void deallocate(OsclAny* p)
    865         {
    866             alloc.deallocate(p);
    867         }
    868         void destruct_and_dealloc(OsclAny* p)
    869         {
    870             T* ptr = reinterpret_cast<T*>(p);
    871             ptr->~T();
    872             deallocate(p);
    873             OSCL_UNUSED_ARG(ptr); // removes warning on some compilers
    874         }
    875     private:
    876         OsclMemBasicAllocator alloc;
    877 };
    878 
    879 /**
    880  * This class is used to get a pointer to the global audit object.
    881  */
    882 
    883 class OsclMemAudit;
    884 class OsclMemGlobalAuditObject
    885 {
    886     public:
    887         typedef OsclMemAudit audit_type;
    888         /**
    889          * returns the global audit object.  For use
    890          * in macros only-- not a public API.
    891          */
    892         OSCL_IMPORT_REF static audit_type* getGlobalMemAuditObject();
    893 
    894     private:
    895         /**
    896          * creates the global audit object
    897          */
    898         static void createGlobalMemAuditObject();
    899 
    900         /**
    901          * deletes the global audit object
    902          */
    903         static void deleteGlobalMemAuditObject();
    904 
    905         friend class OsclMem;
    906 };
    907 
    908 /**
    909 * HeapBase is the base class for all classes that allocates memory.
    910 *
    911 * HeapBase has overloaded new and delete operators.
    912 *
    913 * Derived from _OsclHeapBase providing CBase* alike pointer and virtual destructor for cleanupstack
    914 * to Push and Pop for cleanup when leave occurs.
    915 *
    916 * HeapBase has a virtual destructor which calls the destructor of all the derived classes.
    917 */
    918 
    919 class HeapBase : public _OsclHeapBase
    920 {
    921     public:
    922 #if (OSCL_HAS_HEAP_BASE_SUPPORT)
    923 
    924 #if(!OSCL_BYPASS_MEMMGT)
    925         static void* operator new(size_t aSize, const char *aFile = NULL, const int aLine = 0)
    926         {
    927 #if(PVMEM_INST_LEVEL>0)
    928             //in case NULL is passed in, record this file & line #
    929             if (!aFile)
    930                 return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    931 #endif
    932             return _oscl_default_audit_new(aSize, aFile, aLine);
    933         }
    934 #else
    935         static void* operator new(size_t aSize)
    936         {
    937             return _oscl_default_new(aSize);
    938         }
    939 #endif
    940 
    941         static void* operator new[](size_t aSize)
    942         {
    943 #if(!OSCL_BYPASS_MEMMGT)
    944             return _oscl_default_audit_new(aSize);
    945 #else
    946             return _oscl_default_new(aSize);
    947 #endif
    948         }
    949 
    950         static void* operator new[](size_t aSize, const char *aFile = NULL, const int aLine = 0)
    951         {
    952 #if(!OSCL_BYPASS_MEMMGT)
    953 #if(PVMEM_INST_LEVEL>0)
    954             //in case NULL is passed in, record this file & line #
    955             if (!aFile)
    956                 return _oscl_default_audit_new(aSize, __FILE__, __LINE__);
    957 #endif
    958             return _oscl_default_audit_new(aSize, aFile, aLine);
    959 #else
    960             OSCL_UNUSED_ARG(aFile);
    961             OSCL_UNUSED_ARG(aLine);
    962             return _oscl_default_new(aSize);
    963 #endif
    964         }
    965 
    966         static void* operator new(size_t aSize, void *aPtr)
    967         {
    968             return aPtr;
    969         }
    970 
    971         static void operator delete(void* aPtr)
    972         {
    973 #if(!OSCL_BYPASS_MEMMGT)
    974             _oscl_audit_free(aPtr);
    975 #else
    976             _oscl_free(aPtr);
    977 #endif
    978         }
    979 
    980         static void operator delete[](void* aPtr)
    981         {
    982 #if(!OSCL_BYPASS_MEMMGT)
    983             _oscl_audit_free(aPtr);
    984 #else
    985             _oscl_free(aPtr);
    986 #endif
    987         }
    988 #endif //OSCL_HAS_HEAP_BASE_SUPPORT
    989         HeapBase() {};
    990         virtual ~HeapBase() {};
    991 };
    992 
    993 /** Internal-use macro to catch leaves
    994 *in constructors.  If the constructor leaves,
    995 *this will free the memory
    996 *before allowing the leave to propagate to the next
    997 *level.  It is the constructor's responsibility to
    998 *cleanup any memory in the partially constructed
    999 *object before leaving.  This cleanup may include
   1000 *cleaning up the base class using the OSCL_CLEANUP_BASE_CLASS
   1001 *macro.
   1002 *
   1003 * @param exp: expression to allocate memory.
   1004 * @param Tptr:variable to hold result.
   1005 * @param T: type
   1006 * @param params: constructor arg list
   1007 * @param freeFunc: delete or free function.
   1008 */
   1009 #define _OSCL_TRAP_NEW(exp,freeFunc,T_ptr,T,params)\
   1010 {\
   1011     int32 __err;\
   1012     OsclAny*__ptr=exp;\
   1013     OSCL_TRY(__err,T_ptr=new(__ptr) T params;);\
   1014     if(__err){\
   1015         freeFunc(__ptr);\
   1016         T_ptr=NULL;\
   1017         OsclError::Leave(__err);\
   1018     }\
   1019 }
   1020 
   1021 /**
   1022  * This macro is used to cleanup the
   1023  * base class in a derived-class constructor
   1024  * just before a leave occurs.
   1025  *
   1026  * @param T: base class name.
   1027  */
   1028 #ifdef PVERROR_IMP_CPP_EXCEPTIONS
   1029 //when using C++ exceptions, base class cleanup is automatic
   1030 #define _OSCL_CLEANUP_BASE_CLASS(T)
   1031 #else
   1032 //otherwise the destructor needs to be called explicitly.
   1033 #define _OSCL_CLEANUP_BASE_CLASS(T) this->T::~T()
   1034 #endif
   1035 
   1036 
   1037 /*! @} */
   1038 
   1039 
   1040 #if (!OSCL_DISABLE_INLINES)
   1041 #include "oscl_mem.inl"
   1042 #endif
   1043 
   1044 #endif // OSCL_MEM_H_INCLUDED
   1045 
   1046 
   1047 
   1048 /*! @} */
   1049 
   1050