Index: trunk/psLib/src/sys/psMemory.h
===================================================================
--- trunk/psLib/src/sys/psMemory.h	(revision 11258)
+++ trunk/psLib/src/sys/psMemory.h	(revision 11265)
@@ -2,14 +2,21 @@
  * @brief Contains the definitions for the memory management system
  *
- * This is the generic memory management system put inbetween the user's high level code and the OS-level
- * memory allocation routines.  This system adds such features as callback routines for memory error events,
- * tracing capabilities, and reference counting.
- *
- * @author Robert Lupton, Princeton University
- * @author Robert DeSonia, MHPCC
- *
- * $Revision: 1.63 $ $Name: not supported by cvs2svn $
- * $Date: 2007-01-24 20:04:00 $
- * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  This is the generic memory management system put inbetween the user's high
+ *  level code and the OS-level memory allocation routines.  This system adds
+ *  such features as callback routines for memory error events, tracing
+ *  capabilities, and reference counting.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *  @author Joshua Hoblitt, University of Hawaii
+ *
+ *  @ingroup MemoryManagement
+ *
+ *  @version $Revision: 1.64 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-01-24 22:14:48 $
+ *
+ *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
 
@@ -24,5 +31,9 @@
 #include "psType.h"
 
-#define P_PS_MEMMAGIC (psPtr)0xdeadbeef   // Magic number in psMemBlock header
+/** @addtogroup MemoryManagement
+ *  @{
+ */
+
+#define P_PS_MEMMAGIC (psU32)0xdeadbeef   // Magic number in psMemBlock header
 
 /// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
@@ -40,7 +51,11 @@
  *  aligned for all storage types.
  */
+
+// The memory overhead of a psMemBlock + the trailing post can be checked in
+// gdb with the following command:
+//      p sizeof(psMemBlock) + sizeof(void*)
 typedef struct psMemBlock
 {
-    const void* startblock;            ///< initialised to p_psMEMMAGIC
+    const psU32 startblock;            ///< initialised to p_psMEMMAGIC
     struct psMemBlock* previousBlock;  ///< previous block in allocation list
     struct psMemBlock* nextBlock;      ///< next block allocation list
@@ -48,10 +63,17 @@
     size_t userMemorySize;             ///< the size of the user-portion of the memory block
     const psMemId id;                  ///< a unique ID for this allocation
+    const pthread_t tid;               ///< set from pthread_self();
     const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
     const unsigned int lineno;         ///< set from __LINE__ in e.g. p_psAlloc
-    pthread_mutex_t refCounterMutex;   ///< mutex to ensure exclusive access to reference counter
+    const char *func;                  ///< set from __func__
+    #ifdef HAVE_BACKTRACE
+
+    const void **backtrace;                  ///< set from backtrace()
+    const size_t backtraceSize;              ///< set from bracktrace()
+    #endif // ifdef HAVE_BACKTRACE
+
     psReferenceCount refCounter;       ///< how many times pointer is referenced
     bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
-    const void* endblock;              ///< initialised to p_psMEMMAGIC
+    const psU32 endblock;              ///< initialised to p_psMEMMAGIC
 }
 psMemBlock;
@@ -81,5 +103,5 @@
 typedef void (*psMemProblemCallback) (
     psMemBlock* ptr,                   ///< the pointer to the problematic memory block.
-    const char *filename,                    ///< the file in which the problem originated
+    const char *file,                  ///< the file in which the problem originated
     unsigned int lineno                ///< the line number in which the problem originated
 );
@@ -108,16 +130,30 @@
 
 #else // #ifdef DOXYGEN
+
+#ifdef __GNUC__
 psPtr p_psAlloc(
     size_t size,                       ///< Size required
-    const char *filename,              ///< File of call
-    unsigned int lineno                ///< Line number of call
-);
+    const char *file,                  ///< File of caller
+    unsigned int lineno,               ///< Line number of caller
+    const char *func                   ///< Function name of caller
+) __attribute__((malloc));
+# else // __GNUC__
+
+    psPtr p_psAlloc(
+        size_t size,                       ///< Size required
+        const char *file,                  ///< File of caller
+        unsigned int lineno,               ///< Line number of caller
+        const char *func                   ///< Function name of caller
+    );
+#endif // __GNUC__
 
 /// Memory allocation. psAlloc sends file and line number to p_psAlloc.
 #ifndef SWIG
-#define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
+#define psAlloc(size) \
+p_psAlloc(size, __FILE__, __LINE__, __func__)
 #endif // ! SWIG
 
 #endif // ! DOXYGEN
+
 
 /** Set the deallocator routine
@@ -128,8 +164,28 @@
  *
  */
+#ifdef DOXYGEN
+
 void psMemSetDeallocator(
     psPtr ptr,                         ///< the memory block to operate on
     psFreeFunc freeFunc                ///< the function to be executed at deallocation
 );
+
+#else // ifdef DOXYGEN
+
+void p_psMemSetDeallocator(
+    psPtr ptr,                          ///< the memory block to operate on
+    psFreeFunc freeFunc,                ///< the function to be executed at deallocation
+    const char *file,                   ///< File of caller
+    unsigned int lineno,                ///< Line number of caller
+    const char *func                    ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemSetDeallocator(ptr, freeFunc) \
+p_psMemSetDeallocator(ptr, freeFunc, __FILE__, __LINE__, __func__);
+#endif // ! SWIG
+
+#endif // ifdef DOXYGEN
+
 
 /** Get the deallocator routine
@@ -142,16 +198,26 @@
  *  @return psFreeFunc    the routine to be called at deallocation.
  */
+#ifdef DOXYGEN
+
 psFreeFunc psMemGetDeallocator(
-    const psPtr ptr                    ///< the memory block
-);
-
-/** Checks the deallocator to see if the pointer matches the desired datatype.
- *
- *  @return bool:       True if type matches, otherwise false.
- */
-bool psMemCheckType(
-    psDataType type,                   ///< The desired psDataType to match
-    psPtr ptr                          ///< The desired pointer to match
-);
+    const psPtr ptr                     ///< the memory block
+);
+
+#else // ifdef DOXYGEN
+
+psFreeFunc p_psMemGetDeallocator(
+    const psPtr ptr,                    ///< the memory block
+    const char *file,                   ///< File of caller
+    unsigned int lineno,                ///< Line number of caller
+    const char *func                    ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemGetDeallocator(ptr) \
+p_psMemGetDeallocator(ptr, __FILE__, __LINE__, __func__)
+#endif // ! SWIG
+
+#endif // ifdef DOXYGEN
+
 
 /** Activate or Deactivate thread safety and mutex locking in the memory management.
@@ -176,4 +242,5 @@
 bool psMemGetThreadSafety(void);
 
+
 /** Set the memory as persistent so that it is ignored when detecting memory leaks.
  *
@@ -186,8 +253,28 @@
  *
  */
+#ifdef DOXYGEN
+
+void psMemSetPersistent(
+    psPtr ptr,                         ///< the memory block to operate on
+    bool value,                        ///< true if memory is persistent, otherwise false
+);
+
+#else // #ifdef DOXYGEN
+
 void p_psMemSetPersistent(
     psPtr ptr,                         ///< the memory block to operate on
-    bool value                         ///< true if memory is persistent, otherwise false
-);
+    bool value,                        ///< true if memory is persistent, otherwise false
+    const char *file,                  ///< File of caller
+    unsigned int lineno,               ///< Line number of caller
+    const char *func                   ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemSetPersistent(ptr, value) \
+p_psMemSetPersistent(ptr, value, __FILE__, __LINE__, __func__);
+#endif // ! SWIG
+
+#endif // DOXYGEN
+
 
 /** Set whether allocated memory is persistent
@@ -198,4 +285,5 @@
  */
 bool p_psMemAllocatePersistent(bool is_persistent); ///< Should all memory allocated be persistent?
+
 
 /** Get the memory's persistent flag.
@@ -208,7 +296,24 @@
  *  @return bool    true if memory is marked persistent, otherwise false.
  */
+#ifdef DOXYGEN
+
+bool psMemGetPersistent(
+    psPtr ptr,                         ///< the memory block to check.
+);
+#else // ifdef DOXYGEN
+
 bool p_psMemGetPersistent(
-    psPtr ptr                          ///< the memory block to check.
-);
+    psPtr ptr,                         ///< the memory block to check.
+    const char *file,                  ///< File of caller
+    unsigned int lineno,               ///< Line number of caller
+    const char *func                   ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemGetPersistent(ptr) \
+p_MemGetPersistent(ptr, __FILE__, __LINE__, __func__);
+#endif // ! SWIG
+
+#endif // DOXYGEN
 
 
@@ -226,17 +331,31 @@
 #else // #ifdef DOXYGEN
 
+#ifdef __GNUC__
 psPtr p_psRealloc(
     psPtr ptr,                         ///< Pointer to re-allocate
     size_t size,                       ///< Size required
-    const char *filename,              ///< File of call
-    unsigned int lineno                ///< Line number of call
-);
+    const char *file,                  ///< File of caller
+    unsigned int lineno,               ///< Line number of caller
+    const char *func                   ///< Function name of caller
+) __attribute__((malloc));
+# else // __GNUC__
+
+    psPtr p_psRealloc(
+        psPtr ptr,                         ///< Pointer to re-allocate
+        size_t size,                       ///< Size required
+        const char *file,                  ///< File of caller
+        unsigned int lineno,               ///< Line number of caller
+        const char *func                   ///< Function name of caller
+    );
+#endif // __GNUC__
 
 /// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
 #ifndef SWIG
-#define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
+#define psRealloc(ptr, size) \
+p_psRealloc(ptr, size, __FILE__, __LINE__, __func__)
 #endif // ! SWIG
 
 #endif // ! DOXYGEN
+
 
 /** Free memory.  This operates much like free().
@@ -249,17 +368,13 @@
 );
 #else // #ifdef DOXYGEN
-void p_psFree(
-    psPtr ptr,                         ///< Pointer to free
-    const char *filename,              ///< File of call
-    unsigned int lineno                ///< Line number of call
-);
 
 /// Free memory.  psFree sends file and line number to p_psFree.
 #ifndef SWIG
-//#define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); *(void**)&(ptr) = NULL; }
-#define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); }
+#define            psFree(ptr) \
+p_psMemDecrRefCounter((psPtr *)ptr, __FILE__, __LINE__, __func__);
 #endif // ! SWIG
 
 #endif // ! DOXYGEN
+
 
 /** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
@@ -290,5 +405,6 @@
  */
 int psMemCheckCorruption(
-    bool abort_on_error                ///< Abort on detecting corruption?
+    FILE *output,                       ///< FILE to write corrupted blocks too
+    bool abort_on_error                 ///< Abort on detecting corruption?
 );
 
@@ -298,8 +414,27 @@
  *
  */
+#ifdef DOXYGEN
+
 psReferenceCount psMemGetRefCounter(
     const psPtr ptr                    ///< Pointer to get refCounter for
 );
 
+#else // ifdef DOXYGEN
+
+psReferenceCount p_psMemGetRefCounter(
+    const psPtr ptr,                   ///< Pointer to get refCounter for
+    const char *file,                  ///< File of call
+    unsigned int lineno,               ///< Line number of call
+    const char *func                   ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemGetRefCounter(ptr) \
+p_psMemGetRefCounter(ptr, __FILE__, __LINE__, __func__)
+#endif // !SWIG
+
+#endif // !DOXYGEN
+
+
 /** Increment reference counter and return the pointer
  *
@@ -308,19 +443,24 @@
  */
 #ifdef DOXYGEN
+
 psPtr psMemIncrRefCounter(
     const psPtr ptr                    ///< Pointer to increment refCounter, and return
 );
-#else
+#else // ifdef DOXYGEN
+
 psPtr p_psMemIncrRefCounter(
-    const psPtr vptr,                  ///< Pointer to increment refCounter, and return
+    const psPtr ptr,                  ///< Pointer to increment refCounter, and return
     const char *file,                  ///< File of call
-    psS32 lineno                       ///< Line number of call
-);
-
-#ifndef SWIG
-#define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
+    unsigned int lineno,               ///< Line number of call
+    const char *func                   ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemIncrRefCounter(ptr) \
+p_psMemIncrRefCounter(ptr, __FILE__, __LINE__, __func__)
 #endif // !SWIG
 
 #endif // !DOXYGEN
+
 
 /** Decrement reference counter and return the pointer
@@ -331,20 +471,26 @@
  */
 #ifdef DOXYGEN
+
 psPtr psMemDecrRefCounter(
     psPtr ptr                         ///< Pointer to decrement refCounter, and return
 );
+
 #else // DOXYGEN
+
 psPtr p_psMemDecrRefCounter(
-    psPtr vptr,                        ///< Pointer to decrement refCounter, and return
+    psPtr ptr,                        ///< Pointer to decrement refCounter, and return
     const char *file,                  ///< File of call
-    psS32 lineno                       ///< Line number of call
-);
-
-#ifndef SWIG
-#define psMemDecrRefCounter(vptr) p_psMemDecrRefCounter(vptr, __FILE__, __LINE__)
+    unsigned int lineno,               ///< Line number of call
+    const char *func                   ///< Function name of caller
+);
+
+#ifndef SWIG
+#define psMemDecrRefCounter(ptr) \
+p_psMemDecrRefCounter(ptr, __FILE__, __LINE__, __func__)
 #endif // !SWIG
 
 #endif // !DOXYGEN
 
+#if 0 // psMemSetRefCounter
 /** Set reference counter and return the pointer
  *
@@ -370,16 +516,5 @@
 
 #endif // !DOXYGEN
-
-/** Set callback for problems.
- *
- *  At various occasions, the memory manager can check the state of the memory
- *  stack. If any of these checks discover that the memory stack is corrupted,
- *  the psMemProblemCallback is called.
- *
- *  @return psMemProblemCallback       old psMemProblemCallback function
- */
-psMemProblemCallback psMemProblemCallbackSet(
-    psMemProblemCallback func          ///< Function to run at memory problem detection
-);
+#endif // psMemSetRefCounter
 
 /** Set callback for out-of-memory.
@@ -471,11 +606,22 @@
 /** return statistics on memory usage
  *
- * @return the total amount of memory owned by psLib; if non-NULL also provide a breakdown
- * into recyclable, allocated, and allocated-and-persistent
+ * @return the total amount of memory owned by psLib; if non-NULL also provide
+ * a breakdown into allocated and allocated-and-persistent
  */
 size_t psMemStats(const bool print, ///< print details as they're found?
                   size_t *allocated, ///< memory that's currently allocated (but not persistent)
-                  size_t *persistent, ///< persistent memory that's currently allocated
-                  size_t *freelist); ///< memory that's waiting to be recycled
+                  size_t *persistent); ///< persistent memory that's currently allocated
+
+/** print detailed information about a psMemBlock
+ *
+ * This function prints a detailed description of a psMemBlock to output.
+ *
+ * @return the return status of fprintf()
+ */
+int psMemBlockPrint(
+    FILE *output,                       ///< FILE to write information too
+    const psMemBlock *memBlock          ///< psMemBlock to be examined
+);
+
 
 /// @} end of SysUtils
