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
1.5.1