Index: /trunk/psLib/src/sys/Makefile.am
===================================================================
--- /trunk/psLib/src/sys/Makefile.am	(revision 11264)
+++ /trunk/psLib/src/sys/Makefile.am	(revision 11265)
@@ -15,4 +15,5 @@
 	psString.c     \
 	psTrace.c      \
+	psType.c       \
     strcasestr.c 
 
Index: /trunk/psLib/src/sys/psAssert.h
===================================================================
--- /trunk/psLib/src/sys/psAssert.h	(revision 11264)
+++ /trunk/psLib/src/sys/psAssert.h	(revision 11265)
@@ -19,5 +19,5 @@
     psMemBlock *mb = (psMemBlock*)(NAME) - 1; \
     if (mb->startblock != P_PS_MEMMAGIC || mb->endblock != P_PS_MEMMAGIC || \
-            *(psPtr *)((int8_t *) (mb + 1) + mb->userMemorySize) != P_PS_MEMMAGIC) { \
+            *(psU32 *)((char *)(mb + 1) + mb->userMemorySize) != P_PS_MEMMAGIC) { \
         psError(PS_ERR_MEMORY_CORRUPTION, false, \
                 "Error: Pointer %s is corrupted or not on the PS memory system.", \
Index: /trunk/psLib/src/sys/psConfigure.c
===================================================================
--- /trunk/psLib/src/sys/psConfigure.c	(revision 11264)
+++ /trunk/psLib/src/sys/psConfigure.c	(revision 11265)
@@ -13,9 +13,14 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-12-06 03:01:42 $
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
@@ -28,6 +33,4 @@
 #include "psError.h"
 #include "psConfigure.h"
-
-#include "config.h"
 
 static char *memCheckName = NULL;       // Filename to which to write results of mem check
@@ -58,18 +61,4 @@
 }
 
-// Print details of a memory problem to the appropriate file
-static void memoryProblem(const psMemBlock *ptr, // the pointer to the problematic memory block.
-                          const char *file, // the file in which the problem originated
-                          int lineno    // the line number in which the problem originated
-                         )
-{
-    fprintf(memCheckFile,
-            "Memory corruption detected in memBlock %lu\n"
-            "\tFile %s, line %d, size %zd\n"
-            "\tPosts: %p %p %p\n",
-            ptr->id, file, lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock,
-            (ptr + 1 + ptr->userMemorySize));
-}
-
 // Check the memory; intended for use on exit, but might be used elsewhere
 void p_psMemoryCheck(void)
@@ -93,6 +82,5 @@
 
     int nCorrupted;                     // Number of corrupted memory blocks
-    (void)psMemProblemCallbackSet((psMemProblemCallback)memoryProblem); // Set callback for corruption
-    nCorrupted = psMemCheckCorruption(false);
+    nCorrupted = psMemCheckCorruption(memCheckFile, false);
     if (nCorrupted > 0) {
         psError(PS_ERR_UNKNOWN, true, "%d memory blocks corrupted; list written to %s.\n", nCorrupted, memCheckName);
Index: /trunk/psLib/src/sys/psError.c
===================================================================
--- /trunk/psLib/src/sys/psError.c	(revision 11264)
+++ /trunk/psLib/src/sys/psError.c	(revision 11265)
@@ -11,9 +11,13 @@
  *  @author Eric Van Alst, MHPCC
  *
- *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-10-24 22:52:56 $
+ *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <stdarg.h>
@@ -55,7 +59,7 @@
     if (psArrayLength(errorStack) < MAX_ERROR_STACK_SIZE) {
         // make the psErr persistent
-        p_psMemSetPersistent(err, true);
-        p_psMemSetPersistent(err->msg, true);
-        p_psMemSetPersistent(err->name, true);
+        psMemSetPersistent(err, true);
+        psMemSetPersistent(err->msg, true);
+        psMemSetPersistent(err->name, true);
 
         psArrayAdd(errorStack, 0, err);
@@ -85,6 +89,6 @@
         // allocate the error stack
         errorStack = psArrayAllocEmpty(MAX_ERROR_STACK_SIZE);
-        p_psMemSetPersistent(errorStack, true);
-        p_psMemSetPersistent(errorStack->data, true);
+        psMemSetPersistent(errorStack, true);
+        psMemSetPersistent(errorStack->data, true);
         // store this threads error stack
         // note that pthread_setspecifc() does not take a pointer as the first
@@ -93,4 +97,26 @@
             psAbort(__func__, "pthread_setspecific() failed");
         }
+    }
+
+    return errorStack;
+}
+
+// This function serves the same purpose of psErrorStackGet() accept it does
+// not alloc the error stack if it DOES NOT already exist.  Unlike
+// psErrorStackGet(), this function is NOT guarenteed to return a valid pointer
+// and it's return status must be checked.
+static psArray *psErrorStackGetNoAlloc(void)
+{
+    // check to see if the error stack key has been initialized
+    pthread_mutex_lock(&lockErrorStack);
+    if (errorStackKeyInitialized == false) {
+        return NULL;
+    }
+    pthread_mutex_unlock(&lockErrorStack);
+
+    // check to see if the error stack for this thread has been allocated
+    psArray *errorStack = NULL;
+    if ((errorStack = pthread_getspecific(errorStack_key)) == NULL) {
+        return NULL;
     }
 
@@ -237,7 +263,7 @@
         psErr *err = errorStack->data[i];
 
-        p_psMemSetPersistent(err, false);
-        p_psMemSetPersistent(err->msg, false);
-        p_psMemSetPersistent(err->name, false);
+        psMemSetPersistent(err, false);
+        psMemSetPersistent(err->msg, false);
+        psMemSetPersistent(err->name, false);
     }
 
@@ -260,7 +286,14 @@
 }
 
+// This function does not allocate any memory so it is safe to call from inside
+// of psMemory.c.  Do not allocate memory in function (or call any functions
+// that do) without first removing it's use from psMemory.c.
 void psErrorStackPrintV(FILE *fd, const char *format, va_list va)
 {
-    psArray *errorStack = psErrorStackGet();
+    psArray *errorStack = psErrorStackGetNoAlloc();
+    // do nothing if the error stack has not been allocated
+    if (!errorStack) {
+        return;
+    }
 
     vfprintf(fd, format, va);
Index: /trunk/psLib/src/sys/psErrorCodes.c.in
===================================================================
--- /trunk/psLib/src/sys/psErrorCodes.c.in	(revision 11264)
+++ /trunk/psLib/src/sys/psErrorCodes.c.in	(revision 11265)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-08-08 23:39:59 $
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -118,10 +118,10 @@
     if (dynamicErrorCodes == NULL) {
         dynamicErrorCodes = psListAlloc(NULL);
-        p_psMemSetPersistent(dynamicErrorCodes,true);
+        psMemSetPersistent(dynamicErrorCodes,true);
 
-        p_psMemSetPersistent(dynamicErrorCodes->iterators,true);
-        p_psMemSetPersistent(dynamicErrorCodes->iterators->data,true);
+        psMemSetPersistent(dynamicErrorCodes->iterators,true);
+        psMemSetPersistent(dynamicErrorCodes->iterators->data,true);
         for (int i = 0; i < dynamicErrorCodes->iterators->n;i++) {
-            p_psMemSetPersistent(dynamicErrorCodes->iterators->data[i],true);
+            psMemSetPersistent(dynamicErrorCodes->iterators->data[i],true);
         }
     }
@@ -130,6 +130,6 @@
         psErrorDescription* err = psErrorDescriptionAlloc(
                                       errors[i].code, errors[i].description);
-        p_psMemSetPersistent(err,true);
-        p_psMemSetPersistent((psPtr)err->description,true);
+        psMemSetPersistent(err,true);
+        psMemSetPersistent((psPtr)err->description,true);
         if (! psListAdd(dynamicErrorCodes,
                         PS_LIST_HEAD,
@@ -140,5 +140,5 @@
                     i);
         }
-        p_psMemSetPersistent(dynamicErrorCodes->head,true);
+        psMemSetPersistent(dynamicErrorCodes->head,true);
         psFree(err);
     }
Index: /trunk/psLib/src/sys/psMemory.c
===================================================================
--- /trunk/psLib/src/sys/psMemory.c	(revision 11264)
+++ /trunk/psLib/src/sys/psMemory.c	(revision 11265)
@@ -3,14 +3,20 @@
 *  @brief Contains the definitions for the memory management system
 *
-*  psMemory.h has additional information and documentation of the routines found in this file.
+*  psMemory.h has additional information and documentation of the routines
+*  found in this file.
 *
 *  @author Robert DeSonia, MHPCC
 *  @author Robert Lupton, Princeton University
+*  @author Joshua Hoblitt, University of Hawaii
 *
-*  @version $Revision: 1.88 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-12-08 11:35:54 $
+*  @version $Revision: 1.89 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-01-24 22:14:48 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #define PS_ALLOW_MALLOC                    // we're allowed to call malloc()
@@ -22,26 +28,70 @@
 #include <assert.h>
 
+#if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
+# include <execinfo.h>
+#endif
+
 #include "psMemory.h"
-#include "psError.h"
-#include "psAssert.h"
-#include "psAbort.h"
-#include "psLogMsg.h"
-#include "psBitSet.h"
-#include "psFits.h"
-#include "psPixels.h"
-#include "psSphereOps.h"
-#include "psMinimizeLMM.h"
-#include "psImageConvolve.h"
-#include "psTime.h"
-#include "psLine.h"
-#include "psRegion.h"
-#include "psHistogram.h"
-
-#define P_PS_LARGE_BLOCK_SIZE 65536        // size where under, we try to recycle
-
-static psS32 checkMemBlock(const psMemBlock* m, const char *funcName);
-static psMemBlock* lastMemBlockAllocated = NULL;
+#include "psError.h"    // for psErrorStackPrint() only
+
+#define MUTEX_LOCK(mutexPtr) \
+if (safeThreads) { \
+    pthread_mutex_lock(mutexPtr); \
+}
+
+#define MUTEX_UNLOCK(mutexPtr) \
+if (safeThreads) { \
+    pthread_mutex_unlock(mutexPtr); \
+}
+
+// psAbort() calls functions that call psAlloc() so it is *UNSAFE* to use it
+// from within the memory subsystem.  Previous implementations tried to do
+// this and would deadlock while trying to allocate memory.
+//
+// Note that psError() is also *UNSAFE* to use from within the memory
+// subsystem.
+#define PS_MEM_ABORT(name, ...) \
+P_PS_MEM_ABORT(__FILE__, __LINE__, __func__, name, __VA_ARGS__)
+
+// psErrorStackPrint() was specifically modified to be safe to call from inside
+// psMemory.c.
+#define P_PS_MEM_ABORT(filename, lineno, func, name, ...) \
+fprintf(stderr, "%s (%s:%d) ", func, filename, lineno); \
+fprintf(stderr, __VA_ARGS__);\
+psErrorStackPrint(stderr, "\nAborting.  Error stack:\n"); \
+fprintf(stderr, "\n");\
+abort();
+
+#define HANDLE_BAD_BLOCK(memBlock, file, lineo, func) \
+if (isBadMemBlock(stderr, memBlock, file, lineo, func)) { \
+    PS_MEM_ABORT(__func__, "Unsafe to Continue\n"); \
+}
+
+static bool isBadMemBlock(FILE *output, const psMemBlock *memBlock, const char *file, unsigned int lineo, const char *func);
+
+// pointer to the last mem block that was allocated
+static psMemBlock *lastMemBlockAllocated = NULL;
+
+// memBlockListMutex protects access to:
+//      lastMemBlockAllocated
+//      safeThreads
+//      memid
+//      memory_is_persistent
+//      "the linked list of mem blocks"
+//      p_psMemAllocID
+//      p_psMemFreeID
+//      memAllocCallback
+//      memFreeCallback
+//      memExhaustedCallback
+//
+// This is a fair ammount of stuff to protect with a single mutex but most of
+// these items are *VERY* low contention items.  The only item that should be
+// performance issue is "the linked list of mem blocks".  If this does become a
+// problem in production use of the list should be disabled as it is really a
+// debugging feature.
+//
+// XXX make the mem block list a build time option
+//
 static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
 
 //private boolean for enabling/disabling thread safety.  Default = enabled.
@@ -51,22 +101,4 @@
 static bool memory_is_persistent = false;
 
-#ifdef PS_MEM_USE_RECYCLE               // Only use recycling if this is set
-#define N_RECYCLE_BINS 14               // number of recycle bins
-#define MAX_RECYCLE 100                 // Maximum number permitted in a recycle bin
-static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER; // Mutex for recycle bins
-static const psS32 recycleBinSize[N_RECYCLE_BINS] = // Size of each bin
-    {
-        8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
-    };
-// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
-static psS32 recycleBinNums[N_RECYCLE_BINS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Number in each bin
-static psMemBlock* recycleMemBlockList[N_RECYCLE_BINS] = // Contents of the bins
-    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-#endif // #ifdef PS_MEM_USE_RECYCLE
-
-#ifdef PS_MEM_DEBUG
-static psMemBlock* deadBlockList;       // a place to put dead memBlocks in debug mode.
-#endif // #ifdef PS_MEM_DEBUG
-
 /**
  * Unique ID for allocated blocks
@@ -79,30 +111,5 @@
 static psPtr memExhaustedCallbackDefault(size_t size)
 {
-    #if PS_MEM_USE_RECYCLE
-    psPtr ptr = NULL;
-    if (safeThreads) {
-        pthread_mutex_lock(&recycleMemBlockListMutex);
-    }
-    // Attempt to free up everything I can find so I can alloc my ptr
-    int bin = N_RECYCLE_BINS - 1;       // Recycle bin
-
-    while (bin >= 0 && ptr == NULL) {
-        while (recycleMemBlockList[bin] != NULL && ptr == NULL) {
-            psMemBlock *old = recycleMemBlockList[bin];
-            recycleMemBlockList[bin] = recycleMemBlockList[bin]->nextBlock;
-            free(old);
-            ptr = malloc(size);
-        }
-        bin--;
-    }
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&recycleMemBlockListMutex);
-    }
-    return ptr;
-    #else  // #ifdef PS_MEM_USE_RECYCLE
-
     return NULL;
-    #endif // #ifdef PS_MEM_USE_RECYCLE
 }
 
@@ -113,5 +120,5 @@
  * isn't resignalled)
  */
-static psMemId memAllocCallbackDefault(const psMemBlock* ptr)
+static psMemId memAllocCallbackDefault(const psMemBlock *memBlock)
 {
     static psMemId incr = 0; // "p_psMemAllocID += incr"
@@ -120,24 +127,9 @@
 }
 
-static psMemId memFreeCallbackDefault(const psMemBlock* ptr)
+static psMemId memFreeCallbackDefault(const psMemBlock *memBlock)
 {
     static psMemId incr = 0; // "p_psMemFreeID += incr"
 
     return incr;
-}
-
-static void memProblemCallbackDefault(psMemBlock* ptr,
-                                      const char *file,
-                                      unsigned int lineno)
-{
-    if (ptr->refCounter < 1) {
-        psError(PS_ERR_MEMORY_CORRUPTION, false,
-                _("Block %lu, allocated at %s:%d, freed multiple times at %s:%d."),
-                (unsigned long)ptr->id, ptr->file, ptr->lineno, file, lineno);
-    }
-
-    if (lineno > 0) {
-        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
-    }
 }
 
@@ -147,38 +139,86 @@
  * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
  */
-static psS32 checkMemBlock(const psMemBlock* m,
-                           const char *funcName)
-{
-    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
-    // we shouldn't call such things as p_psAlloc/p_psFree here.
-
-    if (m == NULL) {
-        psError(PS_ERR_MEMORY_CORRUPTION, true,
-                _("NULL memory block found."));
-        return 1;
-    }
-
-    if (m->refCounter == 0) {
+static bool isBadMemBlock(FILE *output, const psMemBlock *memBlock, const char *file, unsigned int lineno, const char *func)
+{
+    // n.b. since this is called by psMemCheckCorruption while the memblock
+    // list is mutex locked, we shouldn't call such things as
+    // p_psAlloc/p_psFree here.
+
+    bool bad = false;
+    bool blockPrinted = false;
+
+    if (memBlock == NULL) {
+        fprintf(output, _("NULL memory block.\n"
+                          "Caught in %s at (%s:%d.).\n\n"), func, file, lineno);
+        // return now as we can't do anything else
+        return true;
+    }
+
+    #if 0
+    // Currently psAlloc()/psRealloc() will blindly create memBlock's with a
+    // size of 0.  This test is in here to check if this is really
+    // happening/being use as a feature in the wild.
+    if (memBlock->userMemorySize < 1) {
+        psMemBlockPrint(output, memBlock);
+        blockPrinted = true;
+        fprintf(output, _("\n\tMemory block has a size of less than 1.\n"));
+        bad = true;
+    }
+    #endif
+
+    if (memBlock->refCounter < 1) {
         // using an unreferenced block of memory, are you?
-        psError(PS_ERR_MEMORY_CORRUPTION, true,
-                _("Memory block %lu was freed but still being used."),
-                (unsigned long)m->id);
-        return 1;
-    }
-
-    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
-        psError(PS_ERR_MEMORY_CORRUPTION, true,
-                _("Memory block %lu is corrupted; buffer underflow detected."),
-                (unsigned long)m->id);
-        return 1;
-    }
-    if (*(psPtr *)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
-        psError(PS_ERR_MEMORY_CORRUPTION, true,
-                _("Memory block %lu is corrupted; buffer overflow detected."),
-                (unsigned long)m->id);
-        return 1;
-    }
-
-    return 0;
+        psMemBlockPrint(output, memBlock);
+        blockPrinted = true;
+        fprintf(output, _("\n\tMemory block was freed but still being used.\n"));
+        bad = true;
+    }
+
+    if (memBlock->startblock != P_PS_MEMMAGIC || memBlock->endblock != P_PS_MEMMAGIC) {
+        if (!blockPrinted) {
+            psMemBlockPrint(output, memBlock);
+            blockPrinted = true;
+        }
+        fprintf(output, _("\n\tMemory block is corrupted; buffer underflow detected.\n"));
+        bad = true;
+    }
+
+    if (*(psU32 *)((char *)(memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
+        if (!blockPrinted) {
+            psMemBlockPrint(output, memBlock);
+            blockPrinted = true;
+        }
+        fprintf(output, _("\n\tMemory block is corrupted; buffer overflow detected.\n"));
+        bad = true;
+    }
+
+    //  XXX ->nextBlock, & -> prevousBlock really should not be looked at by
+    //  this function as they may be changed out from underneath us by new
+    //  memory allocation.  However, the memBlock itself shouldn't go away (end
+    //  users responsiblity) so all we're really risking is a garbage value.
+
+    if (memBlock == memBlock->nextBlock) {
+        if (!blockPrinted) {
+            psMemBlockPrint(output, memBlock);
+            blockPrinted = true;
+        }
+        fprintf(output, _("\n\tMemory block's ->nextBlock pointer refers to itself.\n"));
+        bad = true;
+    }
+
+    if (memBlock == memBlock->previousBlock) {
+        if (!blockPrinted) {
+            psMemBlockPrint(output, memBlock);
+            blockPrinted = true;
+        }
+        fprintf(output, _("\n\tMemory block's ->previousBlock pointer refers to itself.\n"));
+        bad = true;
+    }
+
+    if (bad) {
+        fprintf(output, _("\tCaught in %s at (%s:%d).\n\n"), func, file, lineno);
+    }
+
+    return bad;
 }
 
@@ -188,11 +228,10 @@
  * with psMem{Alloc,Free}CallbackSet
  */
-static psMemId memAllocCallbackCheckCorruption(const psMemBlock *ptr)
+static psMemId memAllocCallbackCheckCorruption(const psMemBlock *memBlock)
 {
     static psMemId incr = 10; // "p_psMemAllocID += incr"
-    bool abort_on_error = false;
-
-    if (psMemCheckCorruption(abort_on_error) > 0) {
-        fprintf(stderr,"Detected memory corruption\n"); // somewhere to set a breakpoint
+
+    if (psMemCheckCorruption(stderr, false) > 0) {
+        fprintf(stderr, "Detected memory corruption\n"); // somewhere to set a breakpoint
     }
 
@@ -205,9 +244,10 @@
 static psMemAllocCallback memAllocCallback = memAllocCallbackDefault;
 static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
-static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
 static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
 
 psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     psMemExhaustedCallback old = memExhaustedCallback;
 
@@ -218,16 +258,5 @@
     }
 
-    return old;
-}
-
-psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
-{
-    psMemProblemCallback old = memProblemCallback;
-
-    if (func != NULL) {
-        memProblemCallback = func;
-    } else {
-        memProblemCallback = memProblemCallbackDefault;
-    }
+    MUTEX_UNLOCK(&memBlockListMutex);
 
     return old;
@@ -244,4 +273,6 @@
 psMemId psMemAllocCallbackSetID(psMemId id)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     psMemId old = p_psMemAllocID;
 
@@ -253,4 +284,6 @@
     p_psMemAllocID = id;
 
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return old;
 }
@@ -258,8 +291,12 @@
 psMemId psMemFreeCallbackSetID(psMemId id)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     psMemId old = p_psMemFreeID;
 
     p_psMemFreeID = id;
 
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return old;
 }
@@ -267,4 +304,6 @@
 psMemAllocCallback psMemAllocCallbackSet(psMemAllocCallback func)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     psMemFreeCallback old = memAllocCallback;
 
@@ -275,4 +314,6 @@
     }
 
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return old;
 }
@@ -280,4 +321,6 @@
 psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     psMemFreeCallback old = memFreeCallback;
 
@@ -288,4 +331,6 @@
     }
 
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return old;
 }
@@ -301,44 +346,28 @@
 psMemId psMemGetLastId(void)
 {
-    if (safeThreads) {
-        pthread_mutex_lock(&memIdMutex);
-    }
+    MUTEX_LOCK(&memBlockListMutex);
 
     psMemId id = memid;
 
-    if (safeThreads) {
-        pthread_mutex_unlock(&memIdMutex);
-    }
+    MUTEX_UNLOCK(&memBlockListMutex);
 
     return id;
 }
 
-int psMemCheckCorruption(bool abort_on_error)
-{
+int psMemCheckCorruption(FILE *output, bool abort_on_error)
+{
+    // get exclusive access to the memBlock list to avoid it changing on us
+    // while we use it.
+    MUTEX_LOCK(&memBlockListMutex);
+
     psS32 nbad = 0;               // number of bad blocks
-    psBool failure = false;
-
-    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
-    //    pthread_mutex_lock(&memBlockListMutex);
-
-    for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) {
-        if (safeThreads) {
-            pthread_mutex_unlock(&memBlockListMutex);
-        }
-        failure = checkMemBlock(iter, __func__);
-        if (safeThreads) {
-            pthread_mutex_lock(&memBlockListMutex);
-        }
-        if ( failure ) {
+    for (psMemBlock *memBlock = lastMemBlockAllocated; memBlock != NULL; memBlock = memBlock->nextBlock) {
+        if (isBadMemBlock(output, memBlock, __FILE__, __LINE__, __func__)) {
             nbad++;
-
-            memProblemCallback(iter, __func__, __LINE__);
 
             if (abort_on_error) {
                 // release the lock on the memblock list
-                if (safeThreads) {
-                    pthread_mutex_unlock(&memBlockListMutex);
-                }
-                psAbort(__func__, "Detected memory corruption");
+                MUTEX_UNLOCK(&memBlockListMutex);
+                PS_MEM_ABORT(__func__, "Detected memory corruption");
                 return nbad;
             }
@@ -347,7 +376,6 @@
 
     // release the lock on the memblock list
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return nbad;
 }
@@ -358,82 +386,13 @@
 bool p_psMemAllocatePersistent(bool is_persistent)
 {
+    MUTEX_LOCK(&memBlockListMutex);
+
     const bool old = memory_is_persistent;
     memory_is_persistent = is_persistent;
 
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     return old;
 }
-
-#ifdef PS_MEM_USE_RECYCLE
-// Return the appropriate recycle bin number
-static int getRecycleBin(size_t size)
-{
-    if (size >= P_PS_LARGE_BLOCK_SIZE) {
-        return N_RECYCLE_BINS;
-    }
-    int binNum = 0;                     // Recycle bin number
-    while (size > recycleBinSize[binNum]) {
-        binNum++;
-    }
-    return binNum;
-}
-
-// Push a pointer onto the recycle bin
-static void recyclePush(psMemBlock *mb, // Pointer to push
-                        int bin         // Recycling bin
-                       )
-{
-    assert(mb);
-    assert(bin < N_RECYCLE_BINS);
-
-    mb->previousBlock = NULL;
-
-    if (safeThreads) {
-        pthread_mutex_lock(&recycleMemBlockListMutex);
-    }
-
-    mb->nextBlock = recycleMemBlockList[bin];
-    if (recycleMemBlockList[bin] != NULL) {
-        recycleMemBlockList[bin]->previousBlock = mb;
-    }
-    recycleMemBlockList[bin] = mb;
-    recycleBinNums[bin]++;
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&recycleMemBlockListMutex);
-    }
-
-    return;
-}
-
-// Pop a pointer from the recycle bin
-static psMemBlock *recyclePop(int bin   // Recycling bin
-                             )
-{
-    if (bin >= N_RECYCLE_BINS) {
-        return NULL;
-    }
-
-    if (safeThreads) {
-        pthread_mutex_lock(&recycleMemBlockListMutex);
-    }
-
-    psMemBlock *mb = recycleMemBlockList[bin]; // Pointer popped from recycle bin
-
-    if (mb) {
-        // We pull it off the list
-        recycleMemBlockList[bin] = mb->nextBlock;
-        if (recycleMemBlockList[bin] != NULL) {
-            recycleMemBlockList[bin]->previousBlock = NULL;
-        }
-        recycleBinNums[bin]--;
-    }
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&recycleMemBlockListMutex);
-    }
-
-    return mb;
-}
-#endif // #ifdef PS_MEM_USE_RECYCLE
 
 /*
@@ -442,169 +401,159 @@
 psPtr p_psAlloc(size_t size,
                 const char *file,
-                unsigned int lineno)
-{
-
-    psMemBlock *ptr = NULL;
-
-    #ifdef PS_MEM_USE_RECYCLE
-    // Are we in one of the recycle bins?
-    int bin = getRecycleBin(size);
-    if (bin < N_RECYCLE_BINS) {
-        size = recycleBinSize[bin];     // round-up size to next sized bin.
-        ptr = recyclePop(bin);          // grab out of the recycle bin
-    }
-    #endif // #ifdef PS_MEM_USE_RECYCLE
-
-    if (ptr == NULL) {
-        ptr = malloc(sizeof(psMemBlock) + size + sizeof(psPtr ));
-
-        if (ptr == NULL) {
-            ptr = memExhaustedCallback(size);
-            if (ptr == NULL) {
-                psAbort(__func__, "Failed to allocate %zd bytes at %s:%d", size, file, lineno);
-            }
-        }
-
-        *(psPtr*)&ptr->startblock = P_PS_MEMMAGIC;
-        *(psPtr*)&ptr->endblock = P_PS_MEMMAGIC;
-        ptr->userMemorySize = size;
-        if (safeThreads) {
-            pthread_mutex_init(&ptr->refCounterMutex, NULL);
-        }
-    }
-    // increment the memory id safely.
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
-    *(psMemId* ) & ptr->id = ++memid;
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
-    ptr->file = file;
-    ptr->freeFunc = NULL;
-    ptr->persistent = memory_is_persistent;
-    *(psU32 *)&ptr->lineno = lineno;
-    *(psPtr *)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
-    ptr->previousBlock = NULL;
-
-    ptr->refCounter = 1;                   // one user so far
+                unsigned int lineno,
+                const char *func)
+{
+
+    psMemBlock *memBlock = malloc(sizeof(psMemBlock) + size + sizeof(psPtr));
+    if (memBlock == NULL) {
+        MUTEX_LOCK(&memBlockListMutex);
+        memBlock = memExhaustedCallback(size);
+        MUTEX_UNLOCK(&memBlockListMutex);
+        if (memBlock == NULL) {
+            PS_MEM_ABORT(__func__, "Failed to allocate %zd bytes at %s (%s:%d)", size, func, file, lineno);
+        }
+    }
+
+    // posts
+    *(psU32 *)&memBlock->startblock = P_PS_MEMMAGIC;
+    *(psU32 *)&memBlock->endblock   = P_PS_MEMMAGIC;
+    *(psU32 *)((char *) (memBlock + 1) + size) = P_PS_MEMMAGIC;
+
+    // size of memory allocated
+    memBlock->userMemorySize = size;
+
+    // alloc request by:
+    // thread
+    *(pthread_t *)&memBlock->tid = pthread_self();
+    // file
+    memBlock->file = file;
+    // line number
+    *(unsigned int *)&memBlock->lineno = (unsigned int)lineno;
+    // function
+    memBlock->func = func;
+
+    #if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
+    #define BACKTRACE_BUFFER_SIZE 32
+    // psMemBlock.func is a 'const char *', so basically we're going to abuse
+    // that and treat it as a void ** to carry around backtrace information.
+    // psMemBlock is not ifdef'd to make sure that psMemBlock is always the
+    // same size & layout reguardless of the pslib .so that's being linked
+    // against
+    void **bt = malloc(BACKTRACE_BUFFER_SIZE * sizeof(void *));
+    if (bt == NULL) {
+        PS_MEM_ABORT(__func__, "Failed to allocate memmory for backtrace buffer: %zd bytes at %s (%s:%d)", 32 * sizeof(void *), func, file, lineno);
+    }
+    *(size_t *)&memBlock->backtraceSize = backtrace(bt, BACKTRACE_BUFFER_SIZE);
+    *(void ***)&memBlock->backtrace = bt;
+    #endif // ifdef HAVE_BACKTRACE
+
+    // free function
+    memBlock->freeFunc = NULL;
+
+    // persistent memory flag
+    memBlock->persistent = memory_is_persistent;
+
+    // this block will be add as the last mem block in the list
+    memBlock->previousBlock = NULL;
+
+    // ref count
+    memBlock->refCounter = 1;                   // one user so far
 
     // need exclusive access of the memory block list now...
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
+    MUTEX_LOCK(&memBlockListMutex);
+
+    // increment the memory id only after we've grabbed the memBlockListMutex
+    *(psMemId* )&memBlock->id = ++memid;
 
     // insert the new block to the front of the memBlock linked-list
-    ptr->nextBlock = lastMemBlockAllocated;
-    if (ptr->nextBlock != NULL) {
-        ptr->nextBlock->previousBlock = ptr;
-    }
-    lastMemBlockAllocated = ptr;
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
+    memBlock->nextBlock = lastMemBlockAllocated;
+    if (memBlock->nextBlock != NULL) {
+        memBlock->nextBlock->previousBlock = memBlock;
+    }
+    lastMemBlockAllocated = memBlock;
 
     // Did the user ask to be informed about this allocation?
-    if (ptr->id == p_psMemAllocID) {
-        p_psMemAllocID += memAllocCallback(ptr);
-    }
+    if (memBlock->id == p_psMemAllocID) {
+        // p_psMemAllocID can only be changed while the memBlockList mutex is
+        // held
+        p_psMemAllocID += memAllocCallback(memBlock);
+    }
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
     // And return the user the memory that they allocated
-    return ptr + 1;                        // user memory
-}
-
-psPtr p_psRealloc(psPtr vptr,
+    return memBlock + 1;                        // user memory
+}
+
+psPtr p_psRealloc(psPtr ptr,
                   size_t size,
                   const char *file,
-                  unsigned int lineno)
-{
-    if (vptr == NULL) {
-        return p_psAlloc(size, file, lineno);
-    }
-
-    psMemBlock *ptr = ((psMemBlock*)vptr) - 1;
-
-    if (checkMemBlock(ptr, __func__) != 0) {
-        memProblemCallback(ptr, file, lineno);
-        psAbort(file, "Realloc detected a memory corruption (id %lu @ %s:%d).",
-                (unsigned long)ptr->id, ptr->file, ptr->lineno);
-    }
-
-    #ifdef PS_MEM_USE_RECYCLE
-    // Ensure the size matches that of the recycle bin
-    int bin = getRecycleBin(size);
-    if (bin < N_RECYCLE_BINS) {
-        size = recycleBinSize[bin];     // round-up size to next sized bin.
-    }
-    #endif // #ifdef PS_MEM_USE_RECYCLE
-
-    if (size == ptr->userMemorySize) {
+                  unsigned int lineno,
+                  const char *func)
+{
+    if (ptr == NULL) {
+        return p_psAlloc(size, file, lineno, func);
+    }
+
+    psMemBlock *memBlock = ((psMemBlock *)ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    if (size == memBlock->userMemorySize) {
         // Nothing to do
-        return vptr;
+        return ptr;
     }
 
     // Reallocate the memory
 
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
-
-    bool isBlockLast = (ptr == lastMemBlockAllocated); // Is this the last block we allocated?
-    ptr = (psMemBlock *)realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr));
-    if (ptr == NULL) {
-        ptr = memExhaustedCallback(size);
-        if (ptr == NULL) {
-            psAbort(__func__, "Failed to reallocate %zd bytes at %s:%d", size, file, lineno);
-        }
-    }
-
-    ptr->userMemorySize = size;
-    *(psPtr *)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
-
+    // Is this the last block we allocated?  If it is, we need to keep track of
+    // this fact and update lastMemBlockAllocated *after* the realloc or
+    // lastMemBlockAllocated will be left with a bogus value
+    bool isBlockLast = (memBlock == lastMemBlockAllocated);
+
+    memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(psPtr));
+    if (memBlock== NULL) {
+        MUTEX_LOCK(&memBlockListMutex);
+        memBlock = memExhaustedCallback(size);
+        if (memBlock == NULL) {
+            MUTEX_UNLOCK(&memBlockListMutex);
+            psMemBlockPrint(stderr,  ((psMemBlock *)ptr) - 1);
+            fprintf(stderr, "Problem reallocating block\n");
+            PS_MEM_ABORT(__func__, "Failed to reallocate to %zd bytes at %s (%s:%d)", size, func, file, lineno);
+        }
+    }
+
+    // realloc() successed so need to update lastMemBlockAllocated if we just
+    // mucked with the last mem block
     if (isBlockLast) {
-        lastMemBlockAllocated = ptr;
+        lastMemBlockAllocated = memBlock;
+    }
+
+    memBlock->userMemorySize = size;
+    *(psU32 *)((char *)(memBlock + 1) + size) = P_PS_MEMMAGIC;
+
+    MUTEX_LOCK(&memBlockListMutex);
+
+    // Is this the last block we allocated?
+    if (memBlock== lastMemBlockAllocated) {
+        lastMemBlockAllocated = memBlock;
     }
 
     // the block location may have changed, so fix the linked list addresses.
-    if (ptr->nextBlock != NULL) {
-        ptr->nextBlock->previousBlock = ptr;
-    }
-    if (ptr->previousBlock != NULL) {
-        ptr->previousBlock->nextBlock = ptr;
-    }
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
+    if (memBlock->nextBlock != NULL) {
+        memBlock->nextBlock->previousBlock = memBlock;
+    }
+    if (memBlock->previousBlock != NULL) {
+        memBlock->previousBlock->nextBlock = memBlock;
     }
 
     // Did the user ask to be informed about this allocation?
-    if (ptr->id == p_psMemAllocID) {
-        p_psMemAllocID += memAllocCallback(ptr);
-    }
-
-    return ptr + 1;                    // usr memory
-}
-
-void p_psFree(psPtr vptr,
-              const char *filename,
-              unsigned int lineno)
-{
-    if (vptr == NULL) {
-        return;
-    }
-    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
-    if (ptr->refCounter < 1) {
-        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
-
-        psAbort(__func__,_("Block %lu, allocated at %s:%d, freed multiple times at %s:%d."),
-                (unsigned long)ptr->id, ptr->file, ptr->lineno, filename, lineno);
-    }
-
-    if (checkMemBlock(ptr, __func__) != 0) {
-        memProblemCallback(ptr, filename, lineno);
-        psAbort(__func__,"Memory Corruption Detected.");
-    }
-
-    (void)p_psMemDecrRefCounter(vptr, filename, lineno);    // this handles the free, if required.
+    if (memBlock->id == p_psMemAllocID) {
+        p_psMemAllocID += memAllocCallback(memBlock);
+    }
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    return memBlock + 1;                    // usr memory
 }
 
@@ -619,14 +568,17 @@
     psS32 nleak = 0;
     psS32 j = 0;
-    psMemBlock* topBlock = lastMemBlockAllocated;
-
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
-
-    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
-        if ( (iter->refCounter > 0) &&
-                ( (persistence) || (!persistence && !iter->persistent) ) &&
-                (iter->id >= id0)) {
+    psMemBlock *topBlock = lastMemBlockAllocated;
+
+    MUTEX_LOCK(&memBlockListMutex);
+
+    // find the very first memblock
+    psMemBlock *memBlock = NULL;
+    for (memBlock = topBlock; memBlock->nextBlock != NULL; memBlock = memBlock->nextBlock) { }
+
+    // iterate through the block list starting with the oldest block
+    for (; memBlock != NULL; memBlock = memBlock->previousBlock) {
+        if ( (memBlock->refCounter > 0) &&
+                ( (persistence) || (!persistence && !memBlock->persistent) ) &&
+                (memBlock->id >= id0)) {
 
             nleak++;
@@ -634,15 +586,50 @@
             if (fd != NULL) {
                 if (nleak == 1) {
-                    fprintf(fd, "   %20s:line ID\n", "file");
+                    fprintf(fd, "# func at (file:line)  ID: X\n");
                 }
 
-                fprintf(fd, "   %20s:%-4d %lu\n", iter->file, (int)iter->lineno, (unsigned long)iter->id);
+                fprintf(fd, "%s at (%s:%d)  ID: %lu", memBlock->func, memBlock->file, (int)memBlock->lineno, (unsigned long)memBlock->id);
+                #if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
+
+                size_t size = memBlock->backtraceSize;
+                char **strings = backtrace_symbols((void *const *)memBlock->backtrace, size);
+
+                fprintf(fd, "  Alloc Call Depth: %zd\n", size);
+
+                for (int i = 0; i < size; i++) {
+                    // always ident
+                    int ident = 4;  // initial indent
+                    ident += 2 * i; // nesting depth
+                    fprintf(fd, "%*s", ident, "");
+
+                    // if the caller was an anon function then strchr won't
+                    // find a '(' in the string and will return NULL
+                    char *caller = caller = strchr(strings[i], '(');
+                    if (caller) {
+                        // skip over the '('
+                        caller++;
+                        // find the end of the symbol name
+                        size_t callerLength = abs(strchr(caller, '+') - caller);
+                        // print just the symbol name
+                        for (int i = 0; i < callerLength; i++) {
+                            fputc(caller[i],fd);
+                        }
+                        fprintf(fd, "\n");
+                    } else {
+                        fprintf(fd, "(unknown)\n");
+                    }
+                }
+
+                free (strings);
+                #else // ifdef HAVE_BACKTRACE
+                // \n after "Memory Block ID"
+                fprintf(fd, "\n");
+                #endif // ifdef HAVE_BACKTRACE
+
             }
         }
     }
 
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
+    MUTEX_UNLOCK(&memBlockListMutex);
 
     if (nleak == 0 || array == NULL) {
@@ -650,15 +637,14 @@
     }
 
-    *array = p_psAlloc(nleak * sizeof(psMemBlock), __FILE__, __LINE__);
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
-
-    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
-        if ( (iter->refCounter > 0) &&
-                ( (persistence) || (!persistence && !iter->persistent) ) &&
-                (iter->id >= id0)) {
-
-            (*array)[j++] = iter;
+    *array = psAlloc(nleak * sizeof(psMemBlock));
+
+    MUTEX_LOCK(&memBlockListMutex);
+
+    for (psMemBlock *memBlock = topBlock; memBlock != NULL; memBlock = memBlock ->nextBlock) {
+        if ( (memBlock->refCounter > 0) &&
+                ( (persistence) || (!persistence && !memBlock->persistent) ) &&
+                (memBlock->id >= id0)) {
+
+            (*array)[j++] = memBlock;
             if (j == nleak) {              // found them all
                 break;
@@ -667,7 +653,5 @@
     }
 
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
+    MUTEX_UNLOCK(&memBlockListMutex);
 
     return nleak;
@@ -679,63 +663,47 @@
 
 // return refCounter
-psReferenceCount psMemGetRefCounter(const psPtr ptr)
-{
-    psMemBlock* ptr2;
-    psU32 refCount;
-
+psReferenceCount p_psMemGetRefCounter(const psPtr ptr,
+                                      const char *file,
+                                      unsigned int lineno,
+                                      const char *func)
+{
     if (ptr == NULL) {
         return 0;
     }
 
-    ptr2 = ((psMemBlock* ) ptr) - 1;
-
-    if (checkMemBlock(ptr2, __func__) != 0) {
-        memProblemCallback(ptr2, __func__, __LINE__);
-    }
-
-    if (safeThreads) {
-        pthread_mutex_lock(&ptr2->refCounterMutex);
-    }
-    refCount = ptr2->refCounter;
-    if (safeThreads) {
-        pthread_mutex_unlock(&ptr2->refCounterMutex);
-    }
-
-    return refCount;
+    psMemBlock *memBlock = ((psMemBlock *) ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    return memBlock->refCounter;
 }
 
 // increment and return refCounter
-psPtr p_psMemIncrRefCounter(const psPtr vptr,
+psPtr p_psMemIncrRefCounter(const psPtr ptr,
                             const char *file,
-                            psS32 lineno)
-{
-    psMemBlock* ptr;
-
-    if (vptr == NULL) {
-        return vptr;
-    }
-
-    ptr = ((psMemBlock* ) vptr) - 1;
-
-    if (checkMemBlock(ptr, __func__)) {
-        memProblemCallback(ptr, file, lineno);
-    }
-
-    if (safeThreads) {
-        pthread_mutex_lock(&ptr->refCounterMutex);
-    }
-    ptr->refCounter++;
-    if (safeThreads) {
-        pthread_mutex_unlock(&ptr->refCounterMutex);
-    }
+                            unsigned int lineno,
+                            const char *func)
+{
+    if (ptr == NULL) {
+        return ptr;
+    }
+
+    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    memBlock->refCounter++;
 
     // Did the user ask to be informed about this allocation?
-    if (ptr->id == p_psMemAllocID) {
-        p_psMemAllocID += memAllocCallback(ptr);
-    }
-
-    return vptr;
-}
-
+    MUTEX_LOCK(&memBlockListMutex);
+    if (memBlock->id == p_psMemAllocID) {
+        p_psMemAllocID += memAllocCallback(memBlock);
+    }
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    return ptr;
+}
+
+#if 0
 psPtr p_psMemSetRefCounter(psPtr vptr,
                            psReferenceCount count,
@@ -755,15 +723,10 @@
     ptr = ((psMemBlock* ) vptr) - 1;
 
-    if (checkMemBlock(ptr, __func__)) {
+    if (isBadMemBlock(ptr, __func__)) {
+        (void)p_psMemDecrRefCounter(vptr, filename, lineno);
         memProblemCallback(ptr, file, lineno);
     }
 
-    if (safeThreads) {
-        pthread_mutex_lock(&ptr->refCounterMutex);
-    }
     ptr->refCounter = count;
-    if (safeThreads) {
-        pthread_mutex_unlock(&ptr->refCounterMutex);
-    }
 
     if (count < 1) {
@@ -773,100 +736,79 @@
     return vptr;
 }
+#endif
 
 // decrement and return refCounter
-psPtr p_psMemDecrRefCounter(psPtr vptr,
+psPtr p_psMemDecrRefCounter(psPtr ptr,
                             const char *file,
-                            psS32 lineno)
-{
-    if (vptr == NULL) {
+                            unsigned int lineno,
+                            const char *func)
+{
+    if (ptr == NULL) {
         return NULL;
     }
 
-    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
-
-    if (checkMemBlock(ptr, __func__) != 0) {
-        memProblemCallback(ptr, file, lineno);
-        return NULL;
-    }
+    psMemBlock *memBlock = ((psMemBlock *) ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    // if we have multiple references, just decrement the count and return.
+    if (memBlock->refCounter > 1) {
+        memBlock->refCounter--;
+
+        // Did the user ask to be informed about this deallocation?
+        MUTEX_LOCK(&memBlockListMutex);
+        if (memBlock->id == p_psMemFreeID) {
+            p_psMemFreeID += memFreeCallback(memBlock);
+        }
+        MUTEX_UNLOCK(&memBlockListMutex);
+
+        return ptr;
+    }
+
+    // we can't invoke freeFunc() while we're holding memBlockListMutex as it
+    // may invoke psFree() itself
+    if (memBlock->freeFunc != NULL) {
+        memBlock->freeFunc(ptr);
+    }
+
+    MUTEX_LOCK(&memBlockListMutex);
 
     // Did the user ask to be informed about this deallocation?
-    if (ptr->id == p_psMemFreeID) {
+    if (memBlock->id == p_psMemFreeID) {
         p_psMemFreeID += memFreeCallback(ptr);
     }
 
-    if (safeThreads) {
-        pthread_mutex_lock(&ptr->refCounterMutex);
-    }
-
-    if (ptr->refCounter > 1) {
-        ptr->refCounter--;                 // multiple references, just decrement the count.
-        if (safeThreads) {
-            pthread_mutex_unlock(&ptr->refCounterMutex);
-        }
-
-    } else {
-        if (safeThreads) {
-            pthread_mutex_unlock(&ptr->refCounterMutex);
-        }
-
-        if (ptr->freeFunc != NULL) {
-            ptr->freeFunc(vptr);
-        }
-
-        if (safeThreads) {
-            pthread_mutex_lock(&memBlockListMutex);
-        }
-
-        // cut the memBlock out of the memBlock list
-        if (ptr->nextBlock != NULL) {
-            ptr->nextBlock->previousBlock = ptr->previousBlock;
-        }
-        if (ptr->previousBlock != NULL) {
-            ptr->previousBlock->nextBlock = ptr->nextBlock;
-        }
-        if (lastMemBlockAllocated == ptr) {
-            lastMemBlockAllocated = ptr->nextBlock;
-        }
-
-        if (safeThreads) {
-            pthread_mutex_unlock(&memBlockListMutex);
-        }
-
-        #ifdef PS_MEM_USE_RECYCLE
-        // do we recycle?
-        int bin = getRecycleBin(ptr->userMemorySize);
-        if (bin < N_RECYCLE_BINS && recycleBinNums[bin] < MAX_RECYCLE) {
-            ptr->refCounter = 0;
-            recyclePush(ptr, bin);
-        } else
-            #endif  // #ifdef PS_MEM_USE_RECYCLE
-            {
-                // memory is larger than I want to recycle.
-                #ifdef PS_MEM_DEBUG
-                (void)p_psRealloc(vptr, 0, file, lineno);
-                ptr->previousBlock = NULL;
-                ptr->nextBlock = deadBlockList;
-                if (deadBlockList != NULL) {
-                deadBlockList->previous = ptr;
-            }
-        deadBlockList = ptr;
-        #else // #ifdef PS_MEM_DEBUG
-
-        if (safeThreads) {
-            pthread_mutex_destroy(&ptr->refCounterMutex);
-            }
-            free(ptr);
-            #endif // #else - #ifdef PS_MEM_DEBUG
-
-        }
-
-        vptr = NULL;                       // since we freed it, make sure we return NULL.
-    }
-
-    return vptr;
-}
-
-void psMemSetDeallocator(psPtr ptr,
-                         psFreeFunc freeFunc)
+    // cut the memBlock out of the memBlock list
+    if (memBlock->nextBlock != NULL) {
+        memBlock->nextBlock->previousBlock = memBlock->previousBlock;
+    }
+    if (memBlock->previousBlock != NULL) {
+        memBlock->previousBlock->nextBlock = memBlock->nextBlock;
+    }
+    if (lastMemBlockAllocated == memBlock) {
+        lastMemBlockAllocated = memBlock->nextBlock;
+    }
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    // invoke free only after we've released the block list lock as free()
+    // could take awhile.  We can get away with this as at this point the
+    // memBlock is no longer part of the mem block list.
+    #if defined(PS_MEM_BACKTRACE) && defined(HAVE_BACKTRACE)
+
+    free(memBlock->backtrace);
+    #endif
+
+    free(memBlock);
+
+    // since we freed it, make sure we return NULL.
+    return NULL;
+}
+
+void p_psMemSetDeallocator(psPtr ptr,
+                           psFreeFunc freeFunc,
+                           const char *file,
+                           unsigned int lineno,
+                           const char *func)
 {
     if (ptr == NULL) {
@@ -874,15 +816,15 @@
     }
 
-    psMemBlock* PTR = ((psMemBlock* ) ptr) - 1;
-
-    if (checkMemBlock(PTR, __func__) != 0) {
-        memProblemCallback(PTR, __func__, __LINE__);
-    }
-
-    PTR->freeFunc = freeFunc;
-
-}
-
-psFreeFunc psMemGetDeallocator(const psPtr ptr)
+    psMemBlock* memBlock = ((psMemBlock *)ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    memBlock->freeFunc = freeFunc;
+}
+
+psFreeFunc p_psMemGetDeallocator(const psPtr ptr,
+                                 const char *file,
+                                 unsigned int lineno,
+                                 const char *func)
 {
     if (ptr == NULL) {
@@ -890,323 +832,65 @@
     }
 
-    psMemBlock* PTR = ((psMemBlock* ) ptr) - 1;
-
-    if (checkMemBlock(PTR, __func__) != 0) {
-        memProblemCallback(PTR, __func__, __LINE__);
-    }
-
-    return PTR->freeFunc;
-}
-
-bool psMemCheckType(psDataType type,
-                    psPtr ptr)
-{
-    PS_ASSERT_PTR(ptr, false);
-
-    switch(type) {
-    case PS_DATA_ARRAY:
-        if ( psMemCheckArray(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_BITSET:
-        if ( psMemCheckBitSet(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_CUBE:
-        if ( psMemCheckCube(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_FITS:
-        if ( psMemCheckFits(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_HASH:
-        if ( psMemCheckHash(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_HISTOGRAM:
-        if ( psMemCheckHistogram(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_IMAGE:
-        if ( psMemCheckImage(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_KERNEL:
-        if ( psMemCheckKernel(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_LINE:
-        if ( psMemCheckLine(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_LIST:
-        if ( psMemCheckList(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_LOOKUPTABLE:
-        if ( psMemCheckLookupTable(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_METADATA:
-        if ( psMemCheckMetadata(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_METADATAITEM:
-        if ( psMemCheckMetadataItem(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_MINIMIZATION:
-        if ( psMemCheckMinimization(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_PIXELS:
-        if ( psMemCheckPixels(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_PLANE:
-        if ( psMemCheckPlane(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_PLANEDISTORT:
-        if ( psMemCheckPlaneDistort(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_PLANETRANSFORM:
-        if ( psMemCheckPlaneTransform(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_POLYNOMIAL1D:
-        if ( psMemCheckPolynomial1D(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_POLYNOMIAL2D:
-        if ( psMemCheckPolynomial2D(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_POLYNOMIAL3D:
-        if ( psMemCheckPolynomial3D(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_POLYNOMIAL4D:
-        if ( psMemCheckPolynomial4D(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_PROJECTION:
-        if ( psMemCheckProjection(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_REGION:
-        if ( psMemCheckRegion(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_SCALAR:
-        if ( psMemCheckScalar(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_SPHERE:
-        if ( psMemCheckSphere(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_SPHEREROT:
-        if ( psMemCheckSphereRot(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_SPLINE1D:
-        if ( psMemCheckSpline1D(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_STATS:
-        if ( psMemCheckStats(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_STRING:
-        if ( psMemCheckString(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_TIME:
-        if ( psMemCheckTime(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    case PS_DATA_VECTOR:
-        if ( psMemCheckVector(ptr) )
-            return true;
-        else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                    "Incorrect pointer.  Datatypes do not match.\n");
-            break;
-        }
-    default:
-        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                "Invalid datatype specified.\n");
-    }
-    return false;
+    psMemBlock* memBlock = ((psMemBlock *)ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    return memBlock->freeFunc;
 }
 
 bool psMemSetThreadSafety(bool safe)
 {
-    bool out = safeThreads;
+    MUTEX_LOCK(&memBlockListMutex);
+
+    bool oldState = safeThreads;
     safeThreads = safe;
-    return out;
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    return oldState;
 }
 
 bool psMemGetThreadSafety(void)
 {
-    return safeThreads;
-}
-
-bool p_psMemGetPersistent(psPtr vptr)
-{
-    if (vptr == NULL) {
+    MUTEX_LOCK(&memBlockListMutex);
+
+    bool oldState = safeThreads;
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    return oldState;
+}
+
+bool p_psMemGetPersistent(psPtr ptr,
+                          const char *file,
+                          unsigned int lineno,
+                          const char *func)
+{
+    if (ptr == NULL) {
         return NULL;
     }
 
-    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
-
-    if (checkMemBlock(ptr, __func__) != 0) {
-        memProblemCallback(ptr, __func__, __LINE__);
-    }
-
-    return ptr->persistent;
-}
-
-void p_psMemSetPersistent(psPtr vptr,
-                          bool value)
-{
-    if (vptr == NULL) {
+    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    return memBlock->persistent;
+}
+
+void p_psMemSetPersistent(psPtr ptr,
+                          bool value,
+                          const char *file,
+                          unsigned int lineno,
+                          const char *func)
+{
+    if (ptr == NULL) {
         return;
     }
 
-    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
-
-    if (checkMemBlock(ptr, __func__) != 0) {
-        memProblemCallback(ptr, __func__, __LINE__);
-    }
-
-    ptr->persistent = value;
+    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
+
+    HANDLE_BAD_BLOCK(memBlock, file, lineno, func);
+
+    memBlock->persistent = value;
 }
 
@@ -1221,6 +905,5 @@
 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
 {
     const size_t overhead = sizeof(psMemBlock) + sizeof(psPtr); // overhead on each allocation
@@ -1230,7 +913,5 @@
     }
 
-    if (safeThreads) {
-        pthread_mutex_lock(&memBlockListMutex);
-    }
+    MUTEX_LOCK(&memBlockListMutex);
     /*
      * All memory that's currently allocated, whether persistent or not
@@ -1264,41 +945,26 @@
         printf("Persistent %6s  %10zd %8zd\n", "", persist, npersist);
     }
-    /*
-     * Count the memory on the free list
-     */
-    size_t freelist_s;
-    if (freelist == NULL) {
-        freelist = &freelist_s;
-    }
-
-    *freelist = 0;
-    int nblock_tot = 0;
-    #ifdef PS_MEM_USE_RECYCLE
-
-    for (int i = 0; recycleBinSize[i] < P_PS_LARGE_BLOCK_SIZE; i++) {
-        size_t bin_contents = 0;
-        size_t nblock = 0;
-        for (const psMemBlock *ptr = recycleMemBlockList[i]; ptr != NULL; ptr = ptr->nextBlock) {
-            nblock++;
-            bin_contents += ptr->userMemorySize + overhead;
-        }
-        *freelist += bin_contents;
-        nblock_tot += nblock;
-
-        if (print) {
-            printf("Freelist   %6d  %10d %8d\n", recycleBinSize[i], bin_contents, nblock);
-        }
-    }
-    #endif // #ifdef PS_MEM_USE_RECYCLE
-
-    if (print) {
-        printf("Freelist   %6s  %10zd %8d\n", "", *freelist, nblock_tot);
-    }
-
-
-    if (safeThreads) {
-        pthread_mutex_unlock(&memBlockListMutex);
-    }
-
-    return *freelist + *allocated + *persistent;
-}
+
+    MUTEX_UNLOCK(&memBlockListMutex);
+
+    return *allocated + *persistent;
+}
+
+int psMemBlockPrint(FILE *output, const psMemBlock *memBlock)
+{
+    return fprintf(output,
+                   "Memory Block ID: %lu @ %p\n"
+                   "\tPrevious Block: %p Next Block: %p\n"
+                   "\tFree function: %p\n"
+                   "\tSize: %zd Reference count: %lu Persistent: %s\n"
+                   "\tPosts: %x %x %x\n"
+                   "\tAllocated in %s at (%s:%d)\n"
+                   "\t\tby Thread ID %lu\n",
+                   memBlock->id, memBlock,
+                   memBlock->previousBlock, memBlock->nextBlock,
+                   memBlock->freeFunc,
+                   memBlock->userMemorySize, memBlock->refCounter, (memBlock->persistent ? "Yes" : "No"),
+                   memBlock->startblock, memBlock->endblock,
+                   *(psU32 *)((char *) (memBlock + 1) + memBlock->userMemorySize),
+                   memBlock->func, memBlock->file, memBlock->lineno, memBlock->tid);
+}
Index: /trunk/psLib/src/sys/psMemory.h
===================================================================
--- /trunk/psLib/src/sys/psMemory.h	(revision 11264)
+++ /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
Index: /trunk/psLib/src/sys/psTrace.c
===================================================================
--- /trunk/psLib/src/sys/psTrace.c	(revision 11264)
+++ /trunk/psLib/src/sys/psTrace.c	(revision 11265)
@@ -9,6 +9,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.79 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-10-13 22:04:58 $
+ *  @version $Revision: 1.80 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -37,4 +37,8 @@
  
  *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #ifndef PS_NO_TRACE
@@ -80,8 +84,8 @@
     p_psComponent* comp = psAlloc(sizeof(p_psComponent));
 
-    p_psMemSetPersistent(comp,true);
+    psMemSetPersistent(comp,true);
     psMemSetDeallocator(comp, (psFreeFunc) componentFree);
     comp->name = psStringCopy(name);
-    p_psMemSetPersistent((psPtr)comp->name,true);
+    psMemSetPersistent((psPtr)comp->name,true);
     comp->level = level;
     comp->n = 0;
@@ -103,12 +107,12 @@
     if (comp->subcomp != NULL) {
         for (psS32 i = 0; i < comp->n; i++) {
-            p_psMemSetPersistent(comp->subcomp[i],false);
+            psMemSetPersistent(comp->subcomp[i],false);
             psFree(comp->subcomp[i]);
         }
-        p_psMemSetPersistent(comp->subcomp,false);
+        psMemSetPersistent(comp->subcomp,false);
         psFree(comp->subcomp);
     }
 
-    p_psMemSetPersistent((psPtr)comp->name,false);
+    psMemSetPersistent((psPtr)comp->name,false);
     psFree(comp->name);
 }
@@ -232,5 +236,5 @@
             currentNode->subcomp = psRealloc(currentNode->subcomp,
                                              (currentNode->n + 1) * sizeof(p_psComponent* ));
-            p_psMemSetPersistent(currentNode->subcomp,true);
+            psMemSetPersistent(currentNode->subcomp,true);
 
             currentNode->n = (currentNode->n) + 1;
Index: /trunk/psLib/src/sys/psType.h
===================================================================
--- /trunk/psLib/src/sys/psType.h	(revision 11264)
+++ /trunk/psLib/src/sys/psType.h	(revision 11265)
@@ -1,16 +1,18 @@
-/* @file  psType.h
- *
- * @brief Contains support for basic types
- *
- * This file defines common datatypes used throughout psLib.
- *
- * @author Robert DeSonia, MHPCC
- * @author Ross Harman, MHPCC
- *
- * @version $Revision: 1.53 $ $Name: not supported by cvs2svn $
- * @date $Date: 2007-01-23 22:47:23 $
- *
- * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
- */
+/** @file  psType.h
+*
+*  @brief Contains support for basic types
+*
+*  This file defines common datatypes used throughout psLib.
+*
+*  @ingroup DataContainer
+*
+*  @author Robert DeSonia, MHPCC
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.54 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-01-24 22:14:48 $
+*
+*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+*/
 
 #ifndef PS_TYPE_H
@@ -298,4 +300,13 @@
 psMath;
 
+/** 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
+);
+
 /// @}
 #endif // #ifndef PS_TYPE_H
Index: /trunk/psLib/test/math/tap_psPolyFit1D.c
===================================================================
--- /trunk/psLib/test/math/tap_psPolyFit1D.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psPolyFit1D.c	(revision 11265)
@@ -318,5 +318,5 @@
     }
 
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     psFree(myPoly);
     psFree(mask);
@@ -327,5 +327,5 @@
     psFree(fErr);
     psFree(stats);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/math/tap_psPolyFit2D.c
===================================================================
--- /trunk/psLib/test/math/tap_psPolyFit2D.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psPolyFit2D.c	(revision 11265)
@@ -328,5 +328,5 @@
     }
 
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     psFree(myPoly);
     psFree(mask);
@@ -339,5 +339,5 @@
     psFree(fErr);
     psFree(stats);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/math/tap_psPolyFit3D.c
===================================================================
--- /trunk/psLib/test/math/tap_psPolyFit3D.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psPolyFit3D.c	(revision 11265)
@@ -375,5 +375,5 @@
     }
 
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     psFree(myPoly);
     psFree(mask);
@@ -388,5 +388,5 @@
     psFree(fErr);
     psFree(stats);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/math/tap_psPolyFit4D.c
===================================================================
--- /trunk/psLib/test/math/tap_psPolyFit4D.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psPolyFit4D.c	(revision 11265)
@@ -431,5 +431,5 @@
     }
 
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     psFree(myPoly);
     psFree(mask);
@@ -446,5 +446,5 @@
     psFree(fErr);
     psFree(stats);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/math/tap_psStats07.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats07.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psStats07.c	(revision 11265)
@@ -484,5 +484,5 @@
     psFree(errors);
     psFree(mask);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/math/tap_psStats09.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats09.c	(revision 11264)
+++ /trunk/psLib/test/math/tap_psStats09.c	(revision 11265)
@@ -335,5 +335,5 @@
     psFree(errors);
     psFree(mask);
-    psMemCheckCorruption(1);
+    psMemCheckCorruption(stderr, false);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
     if (0 != memLeaks) {
Index: /trunk/psLib/test/mathtypes/tap_psVectorSort_01.c
===================================================================
--- /trunk/psLib/test/mathtypes/tap_psVectorSort_01.c	(revision 11264)
+++ /trunk/psLib/test/mathtypes/tap_psVectorSort_01.c	(revision 11265)
@@ -12,6 +12,6 @@
  *  @author  Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
- *  @date  $Date: 2006-12-18 19:10:56 $
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -147,5 +147,5 @@
     ok ( ! psMemCheckLeaks(0, NULL, stdout, false),"Memory leaks not detected");
 
-    psS32 nBad = psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(stderr, false);
     ok(!nBad, "Found %d bad memory blocks\n", nBad);
 }
Index: /trunk/psLib/test/mathtypes/tap_psVectorSort_02.c
===================================================================
--- /trunk/psLib/test/mathtypes/tap_psVectorSort_02.c	(revision 11264)
+++ /trunk/psLib/test/mathtypes/tap_psVectorSort_02.c	(revision 11265)
@@ -14,6 +14,6 @@
  *  @author  Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
- *  @date  $Date: 2006-12-18 19:10:56 $
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -130,5 +130,5 @@
     psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
     ok(!nLeaks, "Found %d memory leaks\n", nLeaks);
-    psS32 nBad = psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(stderr, false);
     ok(!nBad, "Found %d bad memory blocks\n", nBad);
 }
Index: /trunk/psLib/test/mathtypes/tap_psVectorSort_03.c
===================================================================
--- /trunk/psLib/test/mathtypes/tap_psVectorSort_03.c	(revision 11264)
+++ /trunk/psLib/test/mathtypes/tap_psVectorSort_03.c	(revision 11265)
@@ -12,6 +12,6 @@
  *  @author  Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
- *  @date  $Date: 2006-12-18 19:10:56 $
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -68,5 +68,5 @@
     psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
     ok(!nLeaks, "Found %d memory leaks\n", nLeaks);
-    psS32 nBad = psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(stderr, false);
     ok(!nBad, "Found %d bad memory blocks\n", nBad);
 }
Index: /trunk/psLib/test/mathtypes/tap_psVectorSort_04.c
===================================================================
--- /trunk/psLib/test/mathtypes/tap_psVectorSort_04.c	(revision 11264)
+++ /trunk/psLib/test/mathtypes/tap_psVectorSort_04.c	(revision 11265)
@@ -9,6 +9,6 @@
  *  @author  Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
- *  @date  $Date: 2006-12-18 19:10:56 $
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2007-01-24 22:14:48 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -37,5 +37,5 @@
     psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
     ok(!nLeaks, "Found %d memory blocks\n", nLeaks);
-    psS32 nBad = psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(stderr, false);
     ok(!nBad, "Found %d bad memory blocks\n", nBad);
 }
