IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 24, 2007, 12:14:48 PM (19 years ago)
Author:
jhoblitt
Message:

merge jch-memory branch - overhaul of memory subsystem

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sys/psMemory.h

    r11258 r11265  
    22 * @brief Contains the definitions for the memory management system
    33 *
    4  * This is the generic memory management system put inbetween the user's high level code and the OS-level
    5  * memory allocation routines.  This system adds such features as callback routines for memory error events,
    6  * tracing capabilities, and reference counting.
    7  *
    8  * @author Robert Lupton, Princeton University
    9  * @author Robert DeSonia, MHPCC
    10  *
    11  * $Revision: 1.63 $ $Name: not supported by cvs2svn $
    12  * $Date: 2007-01-24 20:04:00 $
    13  * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     4 *  @brief Contains the definitions for the memory management system
     5 *
     6 *  This is the generic memory management system put inbetween the user's high
     7 *  level code and the OS-level memory allocation routines.  This system adds
     8 *  such features as callback routines for memory error events, tracing
     9 *  capabilities, and reference counting.
     10 *
     11 *  @author Robert DeSonia, MHPCC
     12 *  @author Robert Lupton, Princeton University
     13 *  @author Joshua Hoblitt, University of Hawaii
     14 *
     15 *  @ingroup MemoryManagement
     16 *
     17 *  @version $Revision: 1.64 $ $Name: not supported by cvs2svn $
     18 *  @date $Date: 2007-01-24 22:14:48 $
     19 *
     20 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    1421 */
    1522
     
    2431#include "psType.h"
    2532
    26 #define P_PS_MEMMAGIC (psPtr)0xdeadbeef   // Magic number in psMemBlock header
     33/** @addtogroup MemoryManagement
     34 *  @{
     35 */
     36
     37#define P_PS_MEMMAGIC (psU32)0xdeadbeef   // Magic number in psMemBlock header
    2738
    2839/// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
     
    4051 *  aligned for all storage types.
    4152 */
     53
     54// The memory overhead of a psMemBlock + the trailing post can be checked in
     55// gdb with the following command:
     56//      p sizeof(psMemBlock) + sizeof(void*)
    4257typedef struct psMemBlock
    4358{
    44     const void* startblock;            ///< initialised to p_psMEMMAGIC
     59    const psU32 startblock;            ///< initialised to p_psMEMMAGIC
    4560    struct psMemBlock* previousBlock;  ///< previous block in allocation list
    4661    struct psMemBlock* nextBlock;      ///< next block allocation list
     
    4863    size_t userMemorySize;             ///< the size of the user-portion of the memory block
    4964    const psMemId id;                  ///< a unique ID for this allocation
     65    const pthread_t tid;               ///< set from pthread_self();
    5066    const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
    5167    const unsigned int lineno;         ///< set from __LINE__ in e.g. p_psAlloc
    52     pthread_mutex_t refCounterMutex;   ///< mutex to ensure exclusive access to reference counter
     68    const char *func;                  ///< set from __func__
     69    #ifdef HAVE_BACKTRACE
     70
     71    const void **backtrace;                  ///< set from backtrace()
     72    const size_t backtraceSize;              ///< set from bracktrace()
     73    #endif // ifdef HAVE_BACKTRACE
     74
    5375    psReferenceCount refCounter;       ///< how many times pointer is referenced
    5476    bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
    55     const void* endblock;              ///< initialised to p_psMEMMAGIC
     77    const psU32 endblock;              ///< initialised to p_psMEMMAGIC
    5678}
    5779psMemBlock;
     
    81103typedef void (*psMemProblemCallback) (
    82104    psMemBlock* ptr,                   ///< the pointer to the problematic memory block.
    83     const char *filename,                    ///< the file in which the problem originated
     105    const char *file,                  ///< the file in which the problem originated
    84106    unsigned int lineno                ///< the line number in which the problem originated
    85107);
     
    108130
    109131#else // #ifdef DOXYGEN
     132
     133#ifdef __GNUC__
    110134psPtr p_psAlloc(
    111135    size_t size,                       ///< Size required
    112     const char *filename,              ///< File of call
    113     unsigned int lineno                ///< Line number of call
    114 );
     136    const char *file,                  ///< File of caller
     137    unsigned int lineno,               ///< Line number of caller
     138    const char *func                   ///< Function name of caller
     139) __attribute__((malloc));
     140# else // __GNUC__
     141
     142    psPtr p_psAlloc(
     143        size_t size,                       ///< Size required
     144        const char *file,                  ///< File of caller
     145        unsigned int lineno,               ///< Line number of caller
     146        const char *func                   ///< Function name of caller
     147    );
     148#endif // __GNUC__
    115149
    116150/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
    117151#ifndef SWIG
    118 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
     152#define psAlloc(size) \
     153p_psAlloc(size, __FILE__, __LINE__, __func__)
    119154#endif // ! SWIG
    120155
    121156#endif // ! DOXYGEN
     157
    122158
    123159/** Set the deallocator routine
     
    128164 *
    129165 */
     166#ifdef DOXYGEN
     167
    130168void psMemSetDeallocator(
    131169    psPtr ptr,                         ///< the memory block to operate on
    132170    psFreeFunc freeFunc                ///< the function to be executed at deallocation
    133171);
     172
     173#else // ifdef DOXYGEN
     174
     175void p_psMemSetDeallocator(
     176    psPtr ptr,                          ///< the memory block to operate on
     177    psFreeFunc freeFunc,                ///< the function to be executed at deallocation
     178    const char *file,                   ///< File of caller
     179    unsigned int lineno,                ///< Line number of caller
     180    const char *func                    ///< Function name of caller
     181);
     182
     183#ifndef SWIG
     184#define psMemSetDeallocator(ptr, freeFunc) \
     185p_psMemSetDeallocator(ptr, freeFunc, __FILE__, __LINE__, __func__);
     186#endif // ! SWIG
     187
     188#endif // ifdef DOXYGEN
     189
    134190
    135191/** Get the deallocator routine
     
    142198 *  @return psFreeFunc    the routine to be called at deallocation.
    143199 */
     200#ifdef DOXYGEN
     201
    144202psFreeFunc psMemGetDeallocator(
    145     const psPtr ptr                    ///< the memory block
    146 );
    147 
    148 /** Checks the deallocator to see if the pointer matches the desired datatype.
    149  *
    150  *  @return bool:       True if type matches, otherwise false.
    151  */
    152 bool psMemCheckType(
    153     psDataType type,                   ///< The desired psDataType to match
    154     psPtr ptr                          ///< The desired pointer to match
    155 );
     203    const psPtr ptr                     ///< the memory block
     204);
     205
     206#else // ifdef DOXYGEN
     207
     208psFreeFunc p_psMemGetDeallocator(
     209    const psPtr ptr,                    ///< the memory block
     210    const char *file,                   ///< File of caller
     211    unsigned int lineno,                ///< Line number of caller
     212    const char *func                    ///< Function name of caller
     213);
     214
     215#ifndef SWIG
     216#define psMemGetDeallocator(ptr) \
     217p_psMemGetDeallocator(ptr, __FILE__, __LINE__, __func__)
     218#endif // ! SWIG
     219
     220#endif // ifdef DOXYGEN
     221
    156222
    157223/** Activate or Deactivate thread safety and mutex locking in the memory management.
     
    176242bool psMemGetThreadSafety(void);
    177243
     244
    178245/** Set the memory as persistent so that it is ignored when detecting memory leaks.
    179246 *
     
    186253 *
    187254 */
     255#ifdef DOXYGEN
     256
     257void psMemSetPersistent(
     258    psPtr ptr,                         ///< the memory block to operate on
     259    bool value,                        ///< true if memory is persistent, otherwise false
     260);
     261
     262#else // #ifdef DOXYGEN
     263
    188264void p_psMemSetPersistent(
    189265    psPtr ptr,                         ///< the memory block to operate on
    190     bool value                         ///< true if memory is persistent, otherwise false
    191 );
     266    bool value,                        ///< true if memory is persistent, otherwise false
     267    const char *file,                  ///< File of caller
     268    unsigned int lineno,               ///< Line number of caller
     269    const char *func                   ///< Function name of caller
     270);
     271
     272#ifndef SWIG
     273#define psMemSetPersistent(ptr, value) \
     274p_psMemSetPersistent(ptr, value, __FILE__, __LINE__, __func__);
     275#endif // ! SWIG
     276
     277#endif // DOXYGEN
     278
    192279
    193280/** Set whether allocated memory is persistent
     
    198285 */
    199286bool p_psMemAllocatePersistent(bool is_persistent); ///< Should all memory allocated be persistent?
     287
    200288
    201289/** Get the memory's persistent flag.
     
    208296 *  @return bool    true if memory is marked persistent, otherwise false.
    209297 */
     298#ifdef DOXYGEN
     299
     300bool psMemGetPersistent(
     301    psPtr ptr,                         ///< the memory block to check.
     302);
     303#else // ifdef DOXYGEN
     304
    210305bool p_psMemGetPersistent(
    211     psPtr ptr                          ///< the memory block to check.
    212 );
     306    psPtr ptr,                         ///< the memory block to check.
     307    const char *file,                  ///< File of caller
     308    unsigned int lineno,               ///< Line number of caller
     309    const char *func                   ///< Function name of caller
     310);
     311
     312#ifndef SWIG
     313#define psMemGetPersistent(ptr) \
     314p_MemGetPersistent(ptr, __FILE__, __LINE__, __func__);
     315#endif // ! SWIG
     316
     317#endif // DOXYGEN
    213318
    214319
     
    226331#else // #ifdef DOXYGEN
    227332
     333#ifdef __GNUC__
    228334psPtr p_psRealloc(
    229335    psPtr ptr,                         ///< Pointer to re-allocate
    230336    size_t size,                       ///< Size required
    231     const char *filename,              ///< File of call
    232     unsigned int lineno                ///< Line number of call
    233 );
     337    const char *file,                  ///< File of caller
     338    unsigned int lineno,               ///< Line number of caller
     339    const char *func                   ///< Function name of caller
     340) __attribute__((malloc));
     341# else // __GNUC__
     342
     343    psPtr p_psRealloc(
     344        psPtr ptr,                         ///< Pointer to re-allocate
     345        size_t size,                       ///< Size required
     346        const char *file,                  ///< File of caller
     347        unsigned int lineno,               ///< Line number of caller
     348        const char *func                   ///< Function name of caller
     349    );
     350#endif // __GNUC__
    234351
    235352/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
    236353#ifndef SWIG
    237 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
     354#define psRealloc(ptr, size) \
     355p_psRealloc(ptr, size, __FILE__, __LINE__, __func__)
    238356#endif // ! SWIG
    239357
    240358#endif // ! DOXYGEN
     359
    241360
    242361/** Free memory.  This operates much like free().
     
    249368);
    250369#else // #ifdef DOXYGEN
    251 void p_psFree(
    252     psPtr ptr,                         ///< Pointer to free
    253     const char *filename,              ///< File of call
    254     unsigned int lineno                ///< Line number of call
    255 );
    256370
    257371/// Free memory.  psFree sends file and line number to p_psFree.
    258372#ifndef SWIG
    259 //#define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); *(void**)&(ptr) = NULL; }
    260 #define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); }
     373#define            psFree(ptr) \
     374p_psMemDecrRefCounter((psPtr *)ptr, __FILE__, __LINE__, __func__);
    261375#endif // ! SWIG
    262376
    263377#endif // ! DOXYGEN
     378
    264379
    265380/** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
     
    290405 */
    291406int psMemCheckCorruption(
    292     bool abort_on_error                ///< Abort on detecting corruption?
     407    FILE *output,                       ///< FILE to write corrupted blocks too
     408    bool abort_on_error                 ///< Abort on detecting corruption?
    293409);
    294410
     
    298414 *
    299415 */
     416#ifdef DOXYGEN
     417
    300418psReferenceCount psMemGetRefCounter(
    301419    const psPtr ptr                    ///< Pointer to get refCounter for
    302420);
    303421
     422#else // ifdef DOXYGEN
     423
     424psReferenceCount p_psMemGetRefCounter(
     425    const psPtr ptr,                   ///< Pointer to get refCounter for
     426    const char *file,                  ///< File of call
     427    unsigned int lineno,               ///< Line number of call
     428    const char *func                   ///< Function name of caller
     429);
     430
     431#ifndef SWIG
     432#define psMemGetRefCounter(ptr) \
     433p_psMemGetRefCounter(ptr, __FILE__, __LINE__, __func__)
     434#endif // !SWIG
     435
     436#endif // !DOXYGEN
     437
     438
    304439/** Increment reference counter and return the pointer
    305440 *
     
    308443 */
    309444#ifdef DOXYGEN
     445
    310446psPtr psMemIncrRefCounter(
    311447    const psPtr ptr                    ///< Pointer to increment refCounter, and return
    312448);
    313 #else
     449#else // ifdef DOXYGEN
     450
    314451psPtr p_psMemIncrRefCounter(
    315     const psPtr vptr,                  ///< Pointer to increment refCounter, and return
     452    const psPtr ptr,                  ///< Pointer to increment refCounter, and return
    316453    const char *file,                  ///< File of call
    317     psS32 lineno                       ///< Line number of call
    318 );
    319 
    320 #ifndef SWIG
    321 #define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
     454    unsigned int lineno,               ///< Line number of call
     455    const char *func                   ///< Function name of caller
     456);
     457
     458#ifndef SWIG
     459#define psMemIncrRefCounter(ptr) \
     460p_psMemIncrRefCounter(ptr, __FILE__, __LINE__, __func__)
    322461#endif // !SWIG
    323462
    324463#endif // !DOXYGEN
     464
    325465
    326466/** Decrement reference counter and return the pointer
     
    331471 */
    332472#ifdef DOXYGEN
     473
    333474psPtr psMemDecrRefCounter(
    334475    psPtr ptr                         ///< Pointer to decrement refCounter, and return
    335476);
     477
    336478#else // DOXYGEN
     479
    337480psPtr p_psMemDecrRefCounter(
    338     psPtr vptr,                        ///< Pointer to decrement refCounter, and return
     481    psPtr ptr,                        ///< Pointer to decrement refCounter, and return
    339482    const char *file,                  ///< File of call
    340     psS32 lineno                       ///< Line number of call
    341 );
    342 
    343 #ifndef SWIG
    344 #define psMemDecrRefCounter(vptr) p_psMemDecrRefCounter(vptr, __FILE__, __LINE__)
     483    unsigned int lineno,               ///< Line number of call
     484    const char *func                   ///< Function name of caller
     485);
     486
     487#ifndef SWIG
     488#define psMemDecrRefCounter(ptr) \
     489p_psMemDecrRefCounter(ptr, __FILE__, __LINE__, __func__)
    345490#endif // !SWIG
    346491
    347492#endif // !DOXYGEN
    348493
     494#if 0 // psMemSetRefCounter
    349495/** Set reference counter and return the pointer
    350496 *
     
    370516
    371517#endif // !DOXYGEN
    372 
    373 /** Set callback for problems.
    374  *
    375  *  At various occasions, the memory manager can check the state of the memory
    376  *  stack. If any of these checks discover that the memory stack is corrupted,
    377  *  the psMemProblemCallback is called.
    378  *
    379  *  @return psMemProblemCallback       old psMemProblemCallback function
    380  */
    381 psMemProblemCallback psMemProblemCallbackSet(
    382     psMemProblemCallback func          ///< Function to run at memory problem detection
    383 );
     518#endif // psMemSetRefCounter
    384519
    385520/** Set callback for out-of-memory.
     
    471606/** return statistics on memory usage
    472607 *
    473  * @return the total amount of memory owned by psLib; if non-NULL also provide a breakdown
    474  * into recyclable, allocated, and allocated-and-persistent
     608 * @return the total amount of memory owned by psLib; if non-NULL also provide
     609 * a breakdown into allocated and allocated-and-persistent
    475610 */
    476611size_t psMemStats(const bool print, ///< print details as they're found?
    477612                  size_t *allocated, ///< memory that's currently allocated (but not persistent)
    478                   size_t *persistent, ///< persistent memory that's currently allocated
    479                   size_t *freelist); ///< memory that's waiting to be recycled
     613                  size_t *persistent); ///< persistent memory that's currently allocated
     614
     615/** print detailed information about a psMemBlock
     616 *
     617 * This function prints a detailed description of a psMemBlock to output.
     618 *
     619 * @return the return status of fprintf()
     620 */
     621int psMemBlockPrint(
     622    FILE *output,                       ///< FILE to write information too
     623    const psMemBlock *memBlock          ///< psMemBlock to be examined
     624);
     625
    480626
    481627/// @} end of SysUtils
Note: See TracChangeset for help on using the changeset viewer.