psMemory.h

Go to the documentation of this file.
00001 /* @file  psMemory.h
00002  * @brief Contains the definitions for the memory management system
00003  *
00004  *  @brief Contains the definitions for the memory management system
00005  *
00006  *  This is the generic memory management system put inbetween the user's high
00007  *  level code and the OS-level memory allocation routines.  This system adds
00008  *  such features as callback routines for memory error events, tracing
00009  *  capabilities, and reference counting.
00010  *
00011  *  @author Robert DeSonia, MHPCC
00012  *  @author Robert Lupton, Princeton University
00013  *  @author Joshua Hoblitt, University of Hawaii
00014  *
00015  *  @ingroup MemoryManagement
00016  *
00017  *  @version $Revision: 1.65 $ $Name:  $
00018  *  @date $Date: 2007/01/30 03:00:50 $
00019  *
00020  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
00021  */
00022 
00023 #ifndef PS_MEMORY_H
00024 #define PS_MEMORY_H
00025 
00026 /// @addtogroup SysUtils System Utilities
00027 /// @{
00028 
00029 #include <stdio.h>                     // needed for FILE
00030 #include <pthread.h>                   // we need a mutex to make this stuff thread safe.
00031 #include "psType.h"
00032 
00033 /** @addtogroup MemoryManagement
00034  *  @{
00035  */
00036 
00037 #define P_PS_MEMMAGIC (psU32)0xdeadbeef   // Magic number in psMemBlock header
00038 
00039 /// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
00040 typedef unsigned long psMemId;
00041 
00042 /// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
00043 typedef unsigned long psReferenceCount;
00044 
00045 /// typedef for deallocator.
00046 typedef void (*psFreeFunc) (void* ptr);
00047 
00048 /** Book-keeping data for storage allocator.
00049  *  N.b. sizeof(psMemBlock) must be chosen such that if ptr is a pointer
00050  *  returned by malloc, then ((char *)ptr + sizeof(psMemBlock)) is properly
00051  *  aligned for all storage types.
00052  */
00053 
00054 // The memory overhead of a psMemBlock + the trailing post can be checked in
00055 // gdb with the following command:
00056 //      p sizeof(psMemBlock) + sizeof(void*)
00057 typedef struct psMemBlock
00058 {
00059     const psU32 startblock;            ///< initialised to p_psMEMMAGIC
00060     struct psMemBlock* previousBlock;  ///< previous block in allocation list
00061     struct psMemBlock* nextBlock;      ///< next block allocation list
00062     psFreeFunc freeFunc;               ///< deallocator.  If NULL, use generic deallocation.
00063     size_t userMemorySize;             ///< the size of the user-portion of the memory block
00064     const psMemId id;                  ///< a unique ID for this allocation
00065     const pthread_t tid;               ///< set from pthread_self();
00066     const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
00067     const unsigned int lineno;         ///< set from __LINE__ in e.g. p_psAlloc
00068     const char *func;                  ///< set from __func__
00069     #ifdef HAVE_BACKTRACE
00070 
00071     const void **backtrace;                  ///< set from backtrace()
00072     const size_t backtraceSize;              ///< set from bracktrace()
00073     #endif // ifdef HAVE_BACKTRACE
00074 
00075     psReferenceCount refCounter;       ///< how many times pointer is referenced
00076     bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
00077     const psU32 endblock;              ///< initialised to p_psMEMMAGIC
00078 }
00079 psMemBlock;
00080 
00081 /** prototype of a basic callback used by memory functions
00082  *
00083  *  @see psMemAllocCallbackSet
00084  */
00085 typedef psMemId(*psMemAllocCallback) (
00086     const psMemBlock* ptr              ///< the psMemBlock just allocated
00087 );
00088 
00089 /** prototype of memory free callback used by memory functions
00090  *
00091  *  @see psMemFreeCallbackSet
00092  */
00093 typedef psMemId(*psMemFreeCallback) (
00094     const psMemBlock* ptr              ///< the psMemBlock being freed
00095 );
00096 
00097 /** prototype of a callback used in error conditions
00098  *
00099  *  This callback should not try to call psAlloc or psFree.
00100  *
00101  *  @see psMemProblemCallbackSet
00102  */
00103 typedef void (*psMemProblemCallback) (
00104     psMemBlock* ptr,                   ///< the pointer to the problematic memory block.
00105     const char *file,                  ///< the file in which the problem originated
00106     unsigned int lineno                ///< the line number in which the problem originated
00107 );
00108 
00109 /** prototype of a callback function used when memory runs out
00110  *
00111  *  @return psPtr pointer to requested buffer of the size size_t, or NULL if memory could not
00112  *          be found.
00113  *
00114  *  @see psMemExhaustedCallbackSet
00115  */
00116 typedef psPtr (*psMemExhaustedCallback) (
00117     size_t size                        ///< the size of buffer required
00118 );
00119 
00120 /** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
00121  *
00122  *  @return psPtr pointer to the allocated buffer. This will not be NULL.
00123  *  @see psFree
00124  */
00125 #ifdef DOXYGEN
00126 
00127 psPtr psAlloc(
00128     size_t size                        ///< Size required
00129 );
00130 
00131 #else // #ifdef DOXYGEN
00132 
00133 #ifdef __GNUC__
00134 psPtr p_psAlloc(
00135     size_t size,                       ///< Size required
00136     const char *file,                  ///< File of caller
00137     unsigned int lineno,               ///< Line number of caller
00138     const char *func                   ///< Function name of caller
00139 ) __attribute__((malloc));
00140 # else // __GNUC__
00141 
00142     psPtr p_psAlloc(
00143         size_t size,                       ///< Size required
00144         const char *file,                  ///< File of caller
00145         unsigned int lineno,               ///< Line number of caller
00146         const char *func                   ///< Function name of caller
00147     );
00148 #endif // __GNUC__
00149 
00150 /// Memory allocation. psAlloc sends file and line number to p_psAlloc.
00151 #ifndef SWIG
00152 #define psAlloc(size) \
00153 p_psAlloc(size, __FILE__, __LINE__, __func__)
00154 #endif // ! SWIG
00155 
00156 #endif // ! DOXYGEN
00157 
00158 
00159 /** Set the deallocator routine
00160  *
00161  *  A deallocator routine can optionally be assigned to a memory block to
00162  *  ensure that associated memory blocks also get freed, e.g., memory buffers
00163  *  referenced within a struct.
00164  *
00165  */
00166 #ifdef DOXYGEN
00167 
00168 void psMemSetDeallocator(
00169     psPtr ptr,                         ///< the memory block to operate on
00170     psFreeFunc freeFunc                ///< the function to be executed at deallocation
00171 );
00172 
00173 #else // ifdef DOXYGEN
00174 
00175 void p_psMemSetDeallocator(
00176     psPtr ptr,                          ///< the memory block to operate on
00177     psFreeFunc freeFunc,                ///< the function to be executed at deallocation
00178     const char *file,                   ///< File of caller
00179     unsigned int lineno,                ///< Line number of caller
00180     const char *func                    ///< Function name of caller
00181 );
00182 
00183 #ifndef SWIG
00184 #define psMemSetDeallocator(ptr, freeFunc) \
00185 p_psMemSetDeallocator(ptr, freeFunc, __FILE__, __LINE__, __func__);
00186 #endif // ! SWIG
00187 
00188 #endif // ifdef DOXYGEN
00189 
00190 
00191 /** Get the deallocator routine
00192  *
00193  *  This function returns the deallocator for a memory block.  A deallocator
00194  *  routine can optionally be assigned to a memory block to ensure that
00195  *  associated memory blocks also get freed, e.g., memory buffers referenced
00196  *  within a struct.
00197  *
00198  *  @return psFreeFunc    the routine to be called at deallocation.
00199  */
00200 #ifdef DOXYGEN
00201 
00202 psFreeFunc psMemGetDeallocator(
00203     const psPtr ptr                     ///< the memory block
00204 );
00205 
00206 #else // ifdef DOXYGEN
00207 
00208 psFreeFunc p_psMemGetDeallocator(
00209     const psPtr ptr,                    ///< the memory block
00210     const char *file,                   ///< File of caller
00211     unsigned int lineno,                ///< Line number of caller
00212     const char *func                    ///< Function name of caller
00213 );
00214 
00215 #ifndef SWIG
00216 #define psMemGetDeallocator(ptr) \
00217 p_psMemGetDeallocator(ptr, __FILE__, __LINE__, __func__)
00218 #endif // ! SWIG
00219 
00220 #endif // ifdef DOXYGEN
00221 
00222 
00223 /** Activate or Deactivate thread safety and mutex locking in the memory management.
00224  *
00225  *  psMemThreadSafety shall turn on thread safety in the memory management functions if
00226  *  safe is true, and deactivate all mutex locking in the memory management functions if
00227  *  safe is false.  The function shall return the previous value of the thread safety.
00228  *  Note that the default behaviour of the library shall be for the locking to be performed.
00229  *
00230  *  @return bool:       The previous value of the thread safety.
00231  */
00232 bool psMemSetThreadSafety(
00233     bool safe                          ///< boolean for turning on/off thread safety
00234 );
00235 
00236 /** Get the current state of thread safety and mutex locking in the memory management.
00237  *
00238  * psMemGetThreadSafety shall return the current state of thread safety in the memory management system.
00239  *
00240  *  @return bool:       The current state of thread safety.
00241  */
00242 bool psMemGetThreadSafety(void);
00243 
00244 
00245 /** Set the memory as persistent so that it is ignored when detecting memory leaks.
00246  *
00247  *  Used to mark a memory block as persistent data within the library,
00248  *  i.e., non user-level data used to hold psLib's state or cache data.  Such
00249  *  examples of this class of memory is psTrace's trace-levels and dynamic
00250  *  error codes.
00251  *
00252  *  Memory marked as persistent is excluded from memory leak checks.
00253  *
00254  */
00255 #ifdef DOXYGEN
00256 
00257 void psMemSetPersistent(
00258     psPtr ptr,                         ///< the memory block to operate on
00259     bool value,                        ///< true if memory is persistent, otherwise false
00260 );
00261 
00262 #else // #ifdef DOXYGEN
00263 
00264 void p_psMemSetPersistent(
00265     psPtr ptr,                         ///< the memory block to operate on
00266     bool value,                        ///< true if memory is persistent, otherwise false
00267     const char *file,                  ///< File of caller
00268     unsigned int lineno,               ///< Line number of caller
00269     const char *func                   ///< Function name of caller
00270 );
00271 
00272 #ifndef SWIG
00273 #define psMemSetPersistent(ptr, value) \
00274 p_psMemSetPersistent(ptr, value, __FILE__, __LINE__, __func__);
00275 #endif // ! SWIG
00276 
00277 #endif // DOXYGEN
00278 
00279 
00280 /** Set whether allocated memory is persistent
00281  *
00282  *  Set whether allocated memory is persistent. The defeault is false.
00283  *
00284  *  @return bool:       The previous value of whether all allocated memory is persistent
00285  */
00286 bool p_psMemAllocatePersistent(bool is_persistent); ///< Should all memory allocated be persistent?
00287 
00288 
00289 /** Get the memory's persistent flag.
00290  *
00291  *  Checks if a memory block has been marked as persistent by
00292  *  p_psMemSetPresistent.
00293  *
00294  *  Memory marked as persistent is excluded from memory leak checks.
00295  *
00296  *  @return bool    true if memory is marked persistent, otherwise false.
00297  */
00298 #ifdef DOXYGEN
00299 
00300 bool psMemGetPersistent(
00301     psPtr ptr,                         ///< the memory block to check.
00302 );
00303 #else // ifdef DOXYGEN
00304 
00305 bool p_psMemGetPersistent(
00306     psPtr ptr,                         ///< the memory block to check.
00307     const char *file,                  ///< File of caller
00308     unsigned int lineno,               ///< Line number of caller
00309     const char *func                   ///< Function name of caller
00310 );
00311 
00312 #ifndef SWIG
00313 #define psMemGetPersistent(ptr) \
00314 p_MemGetPersistent(ptr, __FILE__, __LINE__, __func__);
00315 #endif // ! SWIG
00316 
00317 #endif // DOXYGEN
00318 
00319 
00320 /** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
00321  *
00322  *  @return psPtr pointer to resized buffer. This will not be NULL.
00323  *  @see psAlloc, psFree
00324  */
00325 #ifdef DOXYGEN
00326 
00327 psPtr psRealloc(
00328     psPtr ptr,                         ///< Pointer to re-allocate
00329     size_t size                        ///< Size required
00330 );
00331 #else // #ifdef DOXYGEN
00332 
00333 #ifdef __GNUC__
00334 psPtr p_psRealloc(
00335     psPtr ptr,                         ///< Pointer to re-allocate
00336     size_t size,                       ///< Size required
00337     const char *file,                  ///< File of caller
00338     unsigned int lineno,               ///< Line number of caller
00339     const char *func                   ///< Function name of caller
00340 ) __attribute__((malloc));
00341 # else // __GNUC__
00342 
00343     psPtr p_psRealloc(
00344         psPtr ptr,                         ///< Pointer to re-allocate
00345         size_t size,                       ///< Size required
00346         const char *file,                  ///< File of caller
00347         unsigned int lineno,               ///< Line number of caller
00348         const char *func                   ///< Function name of caller
00349     );
00350 #endif // __GNUC__
00351 
00352 /// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
00353 #ifndef SWIG
00354 #define psRealloc(ptr, size) \
00355 p_psRealloc(ptr, size, __FILE__, __LINE__, __func__)
00356 #endif // ! SWIG
00357 
00358 #endif // ! DOXYGEN
00359 
00360 
00361 /** Free memory.  This operates much like free().
00362  *
00363  *  @see psAlloc, psRealloc
00364  */
00365 #ifdef DOXYGEN
00366 void psFree(
00367     psPtr ptr                          ///< Pointer to free, if NULL, function returns immediately.
00368 );
00369 #else // #ifdef DOXYGEN
00370 
00371 /// Free memory.  psFree sends file and line number to p_psFree.
00372 #ifndef SWIG
00373 #define            psFree(ptr) \
00374 p_psMemDecrRefCounter((psPtr *)ptr, __FILE__, __LINE__, __func__);
00375 #endif // ! SWIG
00376 
00377 #endif // ! DOXYGEN
00378 
00379 
00380 /** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
00381  *  This is used to check for memory leaks by:
00382  *      -# before a block of code to be checked, store the current ID count via psGetMemId
00383  *      -# after the block of code to be checked, call this function using the ID stored above.  If all
00384  *         memory in the block that was allocated has been freed, this call should output nothing and
00385  *         return 0.
00386  *
00387  *  If memory leaks are found, the Memory Problem callback will be called as well.
00388  *
00389  *  @return int  number of memory blocks found as 'leaks', i.e., the number of currently allocated memory
00390  *              blocks above id0 that have not been freed.
00391  *  @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet
00392  */
00393 #ifdef DOXYGEN
00394 int psMemCheckLeaks(
00395     psMemId id0,                       ///< don't list blocks with id < id0
00396     psMemBlock ***array,               ///< pointer to array of pointers to leaked blocks, or NULL
00397     FILE * fd,                         ///< print list of leaks to fd (or NULL)
00398     bool persistence                   ///< make check across all object even persistent ones
00399 );
00400 #else // ifdef DOXYGEN
00401 int p_psMemCheckLeaks(
00402     psMemId id0,                       ///< don't list blocks with id < id0
00403     psMemBlock ***array,               ///< pointer to array of pointers to leaked blocks, or NULL
00404     FILE * fd,                         ///< print list of leaks to fd (or NULL)
00405     bool persistence,                  ///< make check across all object even persistent ones
00406     const char *file,                   ///< File of caller
00407     unsigned int lineno,                ///< Line number of caller
00408     const char *func                    ///< Function name of caller
00409 );
00410 #ifndef SWIG
00411 #define psMemCheckLeaks(id0, array, fd, persistence) \
00412 p_psMemCheckLeaks(id0, array, fd, persistence, __FILE__, __LINE__, __func__)
00413 #endif // ifndef SWIG
00414 #endif // ifdef DOXYGEN
00415 
00416 
00417 /** Check for memory corruption.  Scans all currently allocated memory buffers and checks for corruptions,
00418  *  i.e., invalid markers that signify a buffer under/overflow.
00419  *
00420  *  @return int
00421  *
00422  */
00423 #ifdef DOXYGEN
00424 int psMemCheckCorruption(
00425     FILE *output,                       ///< FILE to write corrupted blocks too
00426     bool abort_on_error                 ///< Abort on detecting corruption?
00427 );
00428 #else // ifdef DOXYGEN
00429 int p_psMemCheckCorruption(
00430     FILE *output,                       ///< FILE to write corrupted blocks too
00431     bool abort_on_error,                ///< Abort on detecting corruption?
00432     const char *file,                   ///< File of caller
00433     unsigned int lineno,                ///< Line number of caller
00434     const char *func                    ///< Function name of caller
00435 );
00436 #ifndef SWIG
00437 #define psMemCheckCorruption(output, abort_on_error) \
00438 p_psMemCheckCorruption(output, abort_on_error, __FILE__, __LINE__, __func__)
00439 #endif // ifndef SWIG
00440 #endif // ifdef DOXYGEN
00441 
00442 
00443 /** Return reference counter
00444  *
00445  *  @return psReferenceCount
00446  *
00447  */
00448 #ifdef DOXYGEN
00449 
00450 psReferenceCount psMemGetRefCounter(
00451     const psPtr ptr                    ///< Pointer to get refCounter for
00452 );
00453 
00454 #else // ifdef DOXYGEN
00455 
00456 psReferenceCount p_psMemGetRefCounter(
00457     const psPtr ptr,                   ///< Pointer to get refCounter for
00458     const char *file,                  ///< File of call
00459     unsigned int lineno,               ///< Line number of call
00460     const char *func                   ///< Function name of caller
00461 );
00462 
00463 #ifndef SWIG
00464 #define psMemGetRefCounter(ptr) \
00465 p_psMemGetRefCounter(ptr, __FILE__, __LINE__, __func__)
00466 #endif // !SWIG
00467 
00468 #endif // !DOXYGEN
00469 
00470 
00471 /** Increment reference counter and return the pointer
00472  *
00473  *  @return psPtr
00474  *
00475  */
00476 #ifdef DOXYGEN
00477 
00478 psPtr psMemIncrRefCounter(
00479     const psPtr ptr                    ///< Pointer to increment refCounter, and return
00480 );
00481 #else // ifdef DOXYGEN
00482 
00483 psPtr p_psMemIncrRefCounter(
00484     const psPtr ptr,                  ///< Pointer to increment refCounter, and return
00485     const char *file,                  ///< File of call
00486     unsigned int lineno,               ///< Line number of call
00487     const char *func                   ///< Function name of caller
00488 );
00489 
00490 #ifndef SWIG
00491 #define psMemIncrRefCounter(ptr) \
00492 p_psMemIncrRefCounter(ptr, __FILE__, __LINE__, __func__)
00493 #endif // !SWIG
00494 
00495 #endif // !DOXYGEN
00496 
00497 
00498 /** Decrement reference counter and return the pointer
00499  *
00500  *
00501  *  @return psPtr    the pointer deremented in refCount, or NULL if pointer is
00502  *                   fully dereferenced.
00503  */
00504 #ifdef DOXYGEN
00505 
00506 psPtr psMemDecrRefCounter(
00507     psPtr ptr                         ///< Pointer to decrement refCounter, and return
00508 );
00509 
00510 #else // DOXYGEN
00511 
00512 psPtr p_psMemDecrRefCounter(
00513     psPtr ptr,                        ///< Pointer to decrement refCounter, and return
00514     const char *file,                  ///< File of call
00515     unsigned int lineno,               ///< Line number of call
00516     const char *func                   ///< Function name of caller
00517 );
00518 
00519 #ifndef SWIG
00520 #define psMemDecrRefCounter(ptr) \
00521 p_psMemDecrRefCounter(ptr, __FILE__, __LINE__, __func__)
00522 #endif // !SWIG
00523 
00524 #endif // !DOXYGEN
00525 
00526 #if 0 // psMemSetRefCounter
00527 /** Set reference counter and return the pointer
00528  *
00529  *  @return psPtr    the pointer with refCount set, or NULL if pointer is
00530  *                   fully dereferenced.
00531  */
00532 #ifdef DOXYGEN
00533 psPtr psMemSetRefCounter(
00534     psPtr ptr,                        ///< Pointer to decrement refCounter, and return
00535     psReferenceCount count            ///< New reference count
00536 );
00537 #else // DOXYGEN
00538 psPtr p_psMemSetRefCounter(
00539     psPtr vptr,                        ///< Pointer to decrement refCounter, and return
00540     psReferenceCount count,            ///< New reference count
00541     const char *file,                  ///< File of call
00542     psS32 lineno                       ///< Line number of call
00543 );
00544 
00545 #ifndef SWIG
00546 #define psMemSetRefCounter(vptr, count) p_psMemSetRefCounter(vptr, count, __FILE__, __LINE__)
00547 #endif // !SWIG
00548 
00549 #endif // !DOXYGEN
00550 #endif // psMemSetRefCounter
00551 
00552 /** Set callback for out-of-memory.
00553  *
00554  *  If not enough memory is available to satisfy a request by psAlloc or
00555  *  psRealloc, these functions attempt to find an alternative solution by
00556  *  calling the psMemExhaustedCallback, a function which may be set by the
00557  *  programmer in appropriate circumstances, rather than immediately fail.
00558  *  The typical use of such a feature may be when a program needs a large
00559  *  chunk of memory to do an operation, but the exact size is not critical.
00560  *  This feature gives the programmer the opportunity to make a smaller
00561  *  request and try again, limiting the size of the operating buffer.
00562  *
00563  *  @return psMemExhaustedCallback     old psMemExhaustedCallback function
00564  */
00565 psMemExhaustedCallback psMemExhaustedCallbackSet(
00566     psMemExhaustedCallback func        ///< Function to run at memory exhaustion
00567 );
00568 
00569 /** Set call back for when a particular memory block is allocated
00570  *
00571  *  A private variable, p_psMemAllocID, can be used to trace the allocation
00572  *  and freeing of specific memory blocks. If p_psMemAllocID is set and a
00573  *  memory block with that ID is allocated, psMemAllocCallback is called
00574  *  just before memory is returned to the calling function.
00575  *
00576  *  @return psMemAllocCallback      old psMemAllocCallback function
00577  */
00578 psMemAllocCallback psMemAllocCallbackSet(
00579     psMemAllocCallback func            ///< Function to run at memory allocation of specific mem block
00580 );
00581 
00582 /** Set call back for when a particular memory block is freed
00583  *
00584  *  A private variable, p_psMemFreeID, can be used to trace the freeing of
00585  *  specific memory blocks. If p_psMemFreeID is set and the memory block with
00586  *  the ID is about to be freed, the psMemFreeCallback callback is called just
00587  *  before the memory block is freed.
00588  *
00589  *  @return psMemFreeCallback          old psMemFreeCallback function
00590  */
00591 psMemFreeCallback psMemFreeCallbackSet(
00592     psMemFreeCallback func             ///< Function to run at memory free of specific mem block
00593 );
00594 
00595 /** get next memory ID
00596  *
00597  *  @return psMemId                 the next memory ID to be used
00598  */
00599 psMemId psMemGetId(void);
00600 
00601 /** get the last memory ID used
00602  *
00603  *  @return psMemId                 the last memory ID used
00604  */
00605 psMemId psMemGetLastId(void);
00606 
00607 /** set p_psMemAllocID to specific id
00608  *
00609  *  A private variable, p_psMemAllocID, can be used to trace the allocation
00610  *  and freeing of specific memory blocks. If p_psMemAllocID is set and a
00611  *  memory block with that ID is allocated, psMemAllocCallback is called
00612  *  just before memory is returned to the calling function.
00613  *
00614  *  @return psMemId
00615  *
00616  *  @see psMemAllocCallbackSet
00617  */
00618 psMemId psMemAllocCallbackSetID(
00619     psMemId id                         ///< ID to set
00620 );
00621 
00622 /** set p_psMemFreeID to id
00623  *
00624  *  A private variable, p_psMemFreeID, can be used to trace the freeing of
00625  *  specific memory blocks. If p_psMemFreeID is set and the memory block with
00626  *  the ID is about to be freed, the psMemFreeCallback callback is called just
00627  *  before the memory block is freed.
00628  *
00629  *  @return psMemId                 the old p_psMemFreeID
00630  *
00631  *  @see psMemFreeCallbackSet
00632  */
00633 psMemId psMemFreeCallbackSetID(
00634     psMemId id                         ///< ID to set
00635 );
00636 
00637 
00638 /** return statistics on memory usage
00639  *
00640  * @return the total amount of memory owned by psLib; if non-NULL also provide
00641  * a breakdown into allocated and allocated-and-persistent
00642  */
00643 size_t psMemStats(const bool print, ///< print details as they're found?
00644                   size_t *allocated, ///< memory that's currently allocated (but not persistent)
00645                   size_t *persistent); ///< persistent memory that's currently allocated
00646 
00647 /** print detailed information about a psMemBlock
00648  *
00649  * This function prints a detailed description of a psMemBlock to output.
00650  *
00651  * @return the return status of fprintf()
00652  */
00653 int psMemBlockPrint(
00654     FILE *output,                       ///< FILE to write information too
00655     const psMemBlock *memBlock          ///< psMemBlock to be examined
00656 );
00657 
00658 
00659 /// @} end of SysUtils
00660 
00661 #ifndef DOXYGEN
00662 
00663 /*
00664  * Ensure that any program using malloc/realloc/free will fail to compile
00665  */
00666 #ifndef PS_ALLOW_MALLOC
00667 #ifdef __GNUC__
00668 #pragma GCC poison malloc realloc calloc free
00669 #else // __GNUC__
00670 #define malloc(S)       _Pragma("error Use of malloc is not allowed.  Use psAlloc instead.")
00671 #define realloc(P,S)    _Pragma("error Use of realloc is not allowed.  Use psRealloc instead.")
00672 #define calloc(S)       _Pragma("error Use of calloc is not allowed.  Use psAlloc instead.")
00673 #define free(P)         _Pragma("error Use of free is not allowed.  Use psFree instead.")
00674 #endif // ! __GNUC__
00675 #endif // #ifndef PS_ALLOW_MALLOC
00676 
00677 #endif // #ifndef DOXYGEN
00678 #endif // #ifndef PS_MEMORY_H

Generated on Fri Feb 2 22:24:35 2007 for pslib by  doxygen 1.5.1