IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 10899


Ignore:
Timestamp:
Jan 4, 2007, 11:09:32 AM (19 years ago)
Author:
jhoblitt
Message:

comment/doc updates
add PS_MEM_ABORT_CORRUPT macro to replace several calls to memProblemCallBack()
remove the funcname parameter from badMemBlock()
remove memIdMutex (use memBlockListMutex instead)
remove PS_MEM_DEBUG & deadBlockList (unused)
improve naming consistency of variables & function parameters
remove memProblemCallbackDefault()
remove psMemProblemCallbackSet()
add mutex locking all over the place
add func parameter to p_psAlloc()
add func parameter to p_psRealloc(0
reorganize p_psAlloc(), p_psRealloc()
remove p_psFree, superseded by p_psMemDecrRefCounter()
tidy up psMemCheckType() to reduce the number of lines of code
add tid (thread ID) & func (function name) fields to psMemBlock
change psFree macro to call p_psMemDecrRefCounter()

Location:
branches/jch-memory/psLib/src/sys
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/jch-memory/psLib/src/sys/psMemory.c

    r10896 r10899  
    77*  @author Robert DeSonia, MHPCC
    88*  @author Robert Lupton, Princeton University
     9*  @author Joshua Hoblitt, University of Hawaii
    910*
    10 *  @version $Revision: 1.88.2.9 $ $Name: not supported by cvs2svn $
    11 *  @date $Date: 2007-01-03 22:25:33 $
     11*  @version $Revision: 1.88.2.10 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2007-01-04 21:09:32 $
    1213*
    1314*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    5253P_PS_MEM_ABORT(__FILE__, __LINE__, __func__, name, __VA_ARGS__)
    5354
     55// psErrorStackPrint() was specifically modified to be safe to call from inside
     56// psMemory.c.
    5457#define P_PS_MEM_ABORT(filename, lineno, func, name, ...) \
    5558fprintf(stderr, "%s (%s:%d) ", func, filename, lineno); \
     
    6972fprintf(stderr, "\n");
    7073
    71 static bool badMemBlock(const psMemBlock* m, const char *funcName);
    72 static psMemBlock* lastMemBlockAllocated = NULL;
     74#define PS_MEM_ABORT_CORRUPT(ptr) \
     75PS_MEM_ABORT(file, "Memory corruption detected in block %lu, allocated at %s (%s:%d) by thread id %lu", \
     76             (unsigned long)ptr->id, \
     77             ptr->func, \
     78             ptr->file, \
     79             ptr->lineno,\
     80             ptr->tid);
     81
     82static bool badMemBlock(const psMemBlock *memBlock);
     83
     84// pointer to the last mem block that was allocated
     85static psMemBlock *lastMemBlockAllocated = NULL;
     86
     87// memBlockListMutex protects access to:
     88//      lastMemBlockAllocated
     89//      safeThreads
     90//      memid
     91//      memory_is_persistent
     92//      "the linked list of mem blocks"
     93//      p_psMemAllocID
     94//      p_psMemFreeID
     95//      memAllocCallback
     96//      memFreeCallback
     97//      memExhaustedCallback
     98//
     99// This is a fair ammount of stuff to protect with a single mutex but most of
     100// these items are *VERY* low contention items.  The only item that should be
     101// performance issue is "the linked list of mem blocks".  If this does become a
     102// problem in production use of the list should be disabled as it is really a
     103// debugging feature.
     104//
     105// XXX make the mem block list a build time option
     106//
    73107static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
    74 static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
    75108
    76109//private boolean for enabling/disabling thread safety.  Default = enabled.
     
    79112// private boolean for deciding if allocated memory is persistent
    80113static bool memory_is_persistent = false;
    81 
    82 #ifdef PS_MEM_DEBUG
    83 static psMemBlock* deadBlockList;       // a place to put dead memBlocks in debug mode.
    84 #endif // #ifdef PS_MEM_DEBUG
    85114
    86115/**
     
    103132 * isn't resignalled)
    104133 */
    105 static psMemId memAllocCallbackDefault(const psMemBlock* ptr)
     134static psMemId memAllocCallbackDefault(const psMemBlock *memBlock)
    106135{
    107136    static psMemId incr = 0; // "p_psMemAllocID += incr"
     
    110139}
    111140
    112 static psMemId memFreeCallbackDefault(const psMemBlock* ptr)
     141static psMemId memFreeCallbackDefault(const psMemBlock *memBlock)
    113142{
    114143    static psMemId incr = 0; // "p_psMemFreeID += incr"
    115144
    116145    return incr;
    117 }
    118 
    119 static void memProblemCallbackDefault(psMemBlock* ptr,
    120                                       const char *file,
    121                                       unsigned int lineno)
    122 {
    123     if (ptr->refCounter < 1) {
    124         PS_MEM_ERROR(PS_ERR_MEMORY_CORRUPTION, false,
    125                      _("Block %lu, allocated at %s:%d, freed multiple times at %s:%d."),
    126                      (unsigned long)ptr->id, ptr->file, ptr->lineno, file, lineno);
    127     }
    128 
    129     if (lineno > 0) {
    130         PS_MEM_ABORT(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
    131     }
    132146}
    133147
     
    137151 * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
    138152 */
    139 static bool badMemBlock(const psMemBlock* m,
    140                         const char *funcName)
    141 {
    142     // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
    143     // we shouldn't call such things as p_psAlloc/p_psFree here.
    144 
    145     if (m == NULL) {
     153static bool badMemBlock(const psMemBlock *memBlock)
     154{
     155    // n.b. since this is called by psMemCheckCorruption while the memblock
     156    // list is mutex locked, we shouldn't call such things as
     157    // p_psAlloc/p_psFree here.
     158
     159    // ->nextBlock, & -> prevousBlock should not be looked at but this function
     160    // as they make be changed out from underneath us by new memory allocation
     161    if (memBlock == NULL) {
    146162        PS_MEM_ERROR(PS_ERR_MEMORY_CORRUPTION, true,
    147163                     _("NULL memory block found."));
     
    149165    }
    150166
    151     if (m->refCounter == 0) {
     167    if (memBlock->refCounter == 0) {
    152168        // using an unreferenced block of memory, are you?
    153169        PS_MEM_ERROR(PS_ERR_MEMORY_CORRUPTION, true,
    154170                     _("Memory block %lu was freed but still being used."),
    155                      (unsigned long)m->id);
     171                     (unsigned long)memBlock->id);
    156172        return true;
    157173    }
    158174
    159     if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
     175    if (memBlock->startblock != P_PS_MEMMAGIC || memBlock->endblock != P_PS_MEMMAGIC) {
    160176        PS_MEM_ERROR(PS_ERR_MEMORY_CORRUPTION, true,
    161177                     _("Memory block %lu is corrupted; buffer underflow detected."),
    162                      (unsigned long)m->id);
     178                     (unsigned long)memBlock->id);
    163179        return true;
    164180    }
    165     if (*(psPtr *)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
     181    if (*(psPtr *)((int8_t *) (memBlock + 1) + memBlock->userMemorySize) != P_PS_MEMMAGIC) {
    166182        PS_MEM_ERROR(PS_ERR_MEMORY_CORRUPTION, true,
    167183                     _("Memory block %lu is corrupted; buffer overflow detected."),
    168                      (unsigned long)m->id);
     184                     (unsigned long)memBlock->id);
    169185        return true;
    170186    }
     
    178194 * with psMem{Alloc,Free}CallbackSet
    179195 */
    180 static psMemId memAllocCallbackCheckCorruption(const psMemBlock *ptr)
     196static psMemId memAllocCallbackCheckCorruption(const psMemBlock *memBlock)
    181197{
    182198    static psMemId incr = 10; // "p_psMemAllocID += incr"
     
    195211static psMemAllocCallback memAllocCallback = memAllocCallbackDefault;
    196212static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
    197 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
    198213static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
    199214
    200215psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
    201216{
     217    MUTEX_LOCK(&memBlockListMutex);
     218
    202219    psMemExhaustedCallback old = memExhaustedCallback;
    203220
     
    208225    }
    209226
    210     return old;
    211 }
    212 
    213 psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
    214 {
    215     psMemProblemCallback old = memProblemCallback;
    216 
    217     if (func != NULL) {
    218         memProblemCallback = func;
    219     } else {
    220         memProblemCallback = memProblemCallbackDefault;
    221     }
     227    MUTEX_UNLOCK(&memBlockListMutex);
    222228
    223229    return old;
     
    234240psMemId psMemAllocCallbackSetID(psMemId id)
    235241{
     242    MUTEX_LOCK(&memBlockListMutex);
     243
    236244    psMemId old = p_psMemAllocID;
    237245
     
    243251    p_psMemAllocID = id;
    244252
     253    MUTEX_UNLOCK(&memBlockListMutex);
     254
    245255    return old;
    246256}
     
    248258psMemId psMemFreeCallbackSetID(psMemId id)
    249259{
     260    MUTEX_LOCK(&memBlockListMutex);
     261
    250262    psMemId old = p_psMemFreeID;
    251263
    252264    p_psMemFreeID = id;
    253265
     266    MUTEX_UNLOCK(&memBlockListMutex);
     267
    254268    return old;
    255269}
     
    257271psMemAllocCallback psMemAllocCallbackSet(psMemAllocCallback func)
    258272{
     273    MUTEX_LOCK(&memBlockListMutex);
     274
    259275    psMemFreeCallback old = memAllocCallback;
    260276
     
    265281    }
    266282
     283    MUTEX_UNLOCK(&memBlockListMutex);
     284
    267285    return old;
    268286}
     
    270288psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
    271289{
     290    MUTEX_LOCK(&memBlockListMutex);
     291
    272292    psMemFreeCallback old = memFreeCallback;
    273293
     
    278298    }
    279299
     300    MUTEX_UNLOCK(&memBlockListMutex);
     301
    280302    return old;
    281303}
     
    291313psMemId psMemGetLastId(void)
    292314{
    293     MUTEX_LOCK(&memIdMutex);
     315    MUTEX_LOCK(&memBlockListMutex);
    294316
    295317    psMemId id = memid;
    296318
    297     MUTEX_UNLOCK(&memIdMutex);
     319    MUTEX_UNLOCK(&memBlockListMutex);
    298320
    299321    return id;
     
    308330    MUTEX_LOCK(&memBlockListMutex);
    309331
    310     for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) {
    311         if (badMemBlock(iter, __func__)) {
     332    for (psMemBlock *memBlock = lastMemBlockAllocated; memBlock != NULL; memBlock = memBlock->nextBlock) {
     333        if (badMemBlock(memBlock)) {
    312334            nbad++;
    313 
    314             memProblemCallback(iter, __func__, __LINE__);
    315335
    316336            if (abort_on_error) {
     
    334354bool p_psMemAllocatePersistent(bool is_persistent)
    335355{
     356    MUTEX_LOCK(&memBlockListMutex);
     357
    336358    const bool old = memory_is_persistent;
    337359    memory_is_persistent = is_persistent;
    338360
     361    MUTEX_UNLOCK(&memBlockListMutex);
     362
    339363    return old;
    340364}
     
    345369psPtr p_psAlloc(size_t size,
    346370                const char *file,
    347                 unsigned int lineno)
    348 {
    349 
    350     psMemBlock *ptr = NULL;
    351 
    352     if (ptr == NULL) {
    353         ptr = malloc(sizeof(psMemBlock) + size + sizeof(psPtr ));
    354 
    355         if (ptr == NULL) {
    356             ptr = memExhaustedCallback(size);
    357             if (ptr == NULL) {
    358                 PS_MEM_ABORT(__func__, "Failed to allocate %zd bytes at %s:%d", size, file, lineno);
    359             }
    360         }
    361 
    362         *(psPtr*)&ptr->startblock = P_PS_MEMMAGIC;
    363         *(psPtr*)&ptr->endblock = P_PS_MEMMAGIC;
    364         ptr->userMemorySize = size;
    365     }
    366 
    367     // increment the memory id safely.
    368     MUTEX_LOCK(&memBlockListMutex);
    369     *(psMemId* ) & ptr->id = ++memid;
    370     MUTEX_UNLOCK(&memBlockListMutex);
    371 
    372     ptr->file = file;
    373     ptr->freeFunc = NULL;
    374     ptr->persistent = memory_is_persistent;
    375     *(psU32 *)&ptr->lineno = lineno;
    376     *(psPtr *)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
    377     ptr->previousBlock = NULL;
    378 
    379     ptr->refCounter = 1;                   // one user so far
     371                unsigned int lineno,
     372                const char *func)
     373{
     374
     375    psMemBlock *memBlock = malloc(sizeof(psMemBlock) + size + sizeof(psPtr));
     376    if (memBlock == NULL) {
     377        MUTEX_LOCK(&memBlockListMutex);
     378        memBlock = memExhaustedCallback(size);
     379        MUTEX_UNLOCK(&memBlockListMutex);
     380        if (memBlock == NULL) {
     381            PS_MEM_ABORT(__func__, "Failed to allocate %zd bytes at %s (%s:%d)", size, func, file, lineno);
     382        }
     383    }
     384
     385    // posts
     386    *(psPtr*)&memBlock->startblock = P_PS_MEMMAGIC;
     387    *(psPtr*)&memBlock->endblock = P_PS_MEMMAGIC;
     388    *(psPtr *)((int8_t *) (memBlock + 1) + size) = P_PS_MEMMAGIC;
     389
     390    // size of memory allocated
     391    memBlock->userMemorySize = size;
     392
     393    // alloc request by:
     394    // thread
     395    *(pthread_t *)&memBlock->tid = pthread_self();
     396    // file
     397    memBlock->file = file;
     398    // line number
     399    *(unsigned int *)&memBlock->lineno = (unsigned int)lineno;
     400    // function
     401    memBlock->func = func;
     402
     403    // free function
     404    memBlock->freeFunc = NULL;
     405
     406    // persistent memory flag
     407    memBlock->persistent = memory_is_persistent;
     408
     409    // this block will be the add as the last mem block in the list
     410    memBlock->previousBlock = NULL;
     411
     412    // ref count
     413    memBlock->refCounter = 1;                   // one user so far
    380414
    381415    // need exclusive access of the memory block list now...
    382416    MUTEX_LOCK(&memBlockListMutex);
    383417
     418    // increment the memory id only after we've grabbed the memBlockListMutex
     419    *(psMemId* )&memBlock->id = ++memid;
     420
    384421    // insert the new block to the front of the memBlock linked-list
    385     ptr->nextBlock = lastMemBlockAllocated;
    386     if (ptr->nextBlock != NULL) {
    387         ptr->nextBlock->previousBlock = ptr;
    388     }
    389     lastMemBlockAllocated = ptr;
    390 
    391     MUTEX_UNLOCK(&memBlockListMutex);
     422    memBlock->nextBlock = lastMemBlockAllocated;
     423    if (memBlock->nextBlock != NULL) {
     424        memBlock->nextBlock->previousBlock = memBlock;
     425    }
     426    lastMemBlockAllocated = memBlock;
    392427
    393428    // Did the user ask to be informed about this allocation?
    394     if (ptr->id == p_psMemAllocID) {
    395         p_psMemAllocID += memAllocCallback(ptr);
    396     }
     429    if (memBlock->id == p_psMemAllocID) {
     430        // p_psMemAllocID can only be changed while the memBlockList mutex is
     431        // held
     432        p_psMemAllocID += memAllocCallback(memBlock);
     433    }
     434
     435    MUTEX_UNLOCK(&memBlockListMutex);
     436
    397437    // And return the user the memory that they allocated
    398     return ptr + 1;                        // user memory
    399 }
    400 
    401 psPtr p_psRealloc(psPtr vptr,
     438    return memBlock + 1;                        // user memory
     439}
     440
     441psPtr p_psRealloc(psPtr ptr,
    402442                  size_t size,
    403443                  const char *file,
    404                   unsigned int lineno)
    405 {
    406     if (vptr == NULL) {
    407         return p_psAlloc(size, file, lineno);
    408     }
    409 
    410     psMemBlock *ptr = ((psMemBlock*)vptr) - 1;
    411 
    412     if (badMemBlock(ptr, __func__) != 0) {
    413         memProblemCallback(ptr, file, lineno);
    414         PS_MEM_ABORT(file, "Realloc detected a memory corruption (id %lu @ %s:%d).",
    415                      (unsigned long)ptr->id, ptr->file, ptr->lineno);
    416     }
    417 
    418     if (size == ptr->userMemorySize) {
     444                  unsigned int lineno,
     445                  const char *func)
     446{
     447    if (ptr == NULL) {
     448        return p_psAlloc(size, file, lineno, func);
     449    }
     450
     451    psMemBlock *memBlock = ((psMemBlock *)ptr) - 1;
     452
     453    if (badMemBlock(memBlock)) {
     454        PS_MEM_ABORT(file, "Memory corruption detected in block %lu, allocated at %s (%s:%d) by thread id %lu",
     455                     (unsigned long)memBlock->id,
     456                     memBlock->func,
     457                     memBlock->file,
     458                     memBlock->lineno,
     459                     memBlock->tid);
     460    }
     461
     462    if (size == memBlock->userMemorySize) {
    419463        // Nothing to do
    420         return vptr;
     464        return ptr;
    421465    }
    422466
    423467    // Reallocate the memory
    424468
    425     MUTEX_LOCK(&memBlockListMutex);
    426 
    427     bool isBlockLast = (ptr == lastMemBlockAllocated); // Is this the last block we allocated?
    428     ptr = (psMemBlock *)realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr));
    429     if (ptr == NULL) {
    430         ptr = memExhaustedCallback(size);
    431         if (ptr == NULL) {
    432             PS_MEM_ABORT(__func__, "Failed to reallocate %zd bytes at %s:%d", size, file, lineno);
    433         }
    434     }
    435 
    436     ptr->userMemorySize = size;
    437     *(psPtr *)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
    438 
    439     if (isBlockLast) {
    440         lastMemBlockAllocated = ptr;
     469    memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(psPtr));
     470    if (memBlock== NULL) {
     471        MUTEX_LOCK(&memBlockListMutex);
     472        memBlock = memExhaustedCallback(size);
     473        if (memBlock == NULL) {
     474            MUTEX_UNLOCK(&memBlockListMutex);
     475            PS_MEM_ABORT(__func__, "Failed to reallocate %zd bytes at %s (%s:%d)", size, func, file, lineno);
     476        }
     477    }
     478
     479    memBlock->userMemorySize = size;
     480    *(psPtr *)((int8_t *) (memBlock + 1) + size) = P_PS_MEMMAGIC;
     481
     482    MUTEX_LOCK(&memBlockListMutex);
     483
     484    // Is this the last block we allocated?
     485    if (memBlock== lastMemBlockAllocated) {
     486        lastMemBlockAllocated = memBlock;
    441487    }
    442488
    443489    // the block location may have changed, so fix the linked list addresses.
    444     if (ptr->nextBlock != NULL) {
    445         ptr->nextBlock->previousBlock = ptr;
    446     }
    447     if (ptr->previousBlock != NULL) {
    448         ptr->previousBlock->nextBlock = ptr;
    449     }
    450 
    451     MUTEX_UNLOCK(&memBlockListMutex);
     490    if (memBlock->nextBlock != NULL) {
     491        memBlock->nextBlock->previousBlock = memBlock;
     492    }
     493    if (memBlock->previousBlock != NULL) {
     494        memBlock->previousBlock->nextBlock = memBlock;
     495    }
    452496
    453497    // Did the user ask to be informed about this allocation?
    454     if (ptr->id == p_psMemAllocID) {
    455         p_psMemAllocID += memAllocCallback(ptr);
    456     }
    457 
    458     return ptr + 1;                    // usr memory
    459 }
    460 
    461 void p_psFree(psPtr vptr,
    462               const char *filename,
    463               unsigned int lineno)
    464 {
    465     if (vptr == NULL) {
    466         return;
    467     }
    468     psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
    469     if (ptr->refCounter < 1) {
    470         psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
    471 
    472         PS_MEM_ABORT(__func__,_("Block %lu, allocated at %s:%d, freed multiple times at %s:%d."),
    473                      (unsigned long)ptr->id, ptr->file, ptr->lineno, filename, lineno);
    474     }
    475 
    476     if (badMemBlock(ptr, __func__) != 0) {
    477         memProblemCallback(ptr, filename, lineno);
    478         PS_MEM_ABORT(__func__,"Memory Corruption Detected.");
    479     }
    480 
    481     (void)p_psMemDecrRefCounter(vptr, filename, lineno);    // this handles the free, if required.
     498    if (memBlock->id == p_psMemAllocID) {
     499        p_psMemAllocID += memAllocCallback(memBlock);
     500    }
     501
     502    MUTEX_UNLOCK(&memBlockListMutex);
     503
     504    return memBlock + 1;                    // usr memory
    482505}
    483506
     
    492515    psS32 nleak = 0;
    493516    psS32 j = 0;
    494     psMemBlock* topBlock = lastMemBlockAllocated;
    495 
    496     MUTEX_LOCK(&memBlockListMutex);
    497 
    498     for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
    499         if ( (iter->refCounter > 0) &&
    500                 ( (persistence) || (!persistence && !iter->persistent) ) &&
    501                 (iter->id >= id0)) {
     517    psMemBlock *topBlock = lastMemBlockAllocated;
     518
     519    MUTEX_LOCK(&memBlockListMutex);
     520
     521    for (psMemBlock *memBlock = topBlock; memBlock != NULL; memBlock = memBlock->nextBlock) {
     522        if ( (memBlock->refCounter > 0) &&
     523                ( (persistence) || (!persistence && !memBlock->persistent) ) &&
     524                (memBlock->id >= id0)) {
    502525
    503526            nleak++;
     
    508531                }
    509532
    510                 fprintf(fd, "   %20s:%-4d %lu\n", iter->file, (int)iter->lineno, (unsigned long)iter->id);
     533                fprintf(fd, "   %20s:%-4d %lu\n", memBlock->file, (int)memBlock->lineno, (unsigned long)memBlock->id);
    511534            }
    512535        }
     
    519542    }
    520543
    521     *array = p_psAlloc(nleak * sizeof(psMemBlock), __FILE__, __LINE__);
    522     MUTEX_LOCK(&memBlockListMutex);
    523 
    524     for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
    525         if ( (iter->refCounter > 0) &&
    526                 ( (persistence) || (!persistence && !iter->persistent) ) &&
    527                 (iter->id >= id0)) {
    528 
    529             (*array)[j++] = iter;
     544    *array = psAlloc(nleak * sizeof(psMemBlock));
     545
     546    MUTEX_LOCK(&memBlockListMutex);
     547
     548    for (psMemBlock *memBlock = topBlock; memBlock != NULL; memBlock = memBlock ->nextBlock) {
     549        if ( (memBlock->refCounter > 0) &&
     550                ( (persistence) || (!persistence && !memBlock->persistent) ) &&
     551                (memBlock->id >= id0)) {
     552
     553            (*array)[j++] = memBlock;
    530554            if (j == nleak) {              // found them all
    531555                break;
     
    546570psReferenceCount psMemGetRefCounter(const psPtr ptr)
    547571{
    548     psMemBlock* ptr2;
    549     psU32 refCount;
    550 
    551572    if (ptr == NULL) {
    552573        return 0;
    553574    }
    554575
    555     ptr2 = ((psMemBlock* ) ptr) - 1;
    556 
    557     if (badMemBlock(ptr2, __func__) != 0) {
    558         memProblemCallback(ptr2, __func__, __LINE__);
    559     }
    560 
    561     refCount = ptr2->refCounter;
    562 
    563     return refCount;
     576    psMemBlock *memBlock = ((psMemBlock *) ptr) - 1;
     577
     578    if (badMemBlock(memBlock)) {
     579        PS_MEM_ABORT_CORRUPT(memBlock);
     580    }
     581
     582    return memBlock->refCounter;
    564583}
    565584
    566585// increment and return refCounter
    567 psPtr p_psMemIncrRefCounter(const psPtr vptr,
     586psPtr p_psMemIncrRefCounter(const psPtr ptr,
    568587                            const char *file,
    569588                            psS32 lineno)
    570589{
    571     psMemBlock* ptr;
    572 
    573     if (vptr == NULL) {
    574         return vptr;
    575     }
    576 
    577     ptr = ((psMemBlock* ) vptr) - 1;
    578 
    579     if (badMemBlock(ptr, __func__)) {
    580         memProblemCallback(ptr, file, lineno);
    581     }
    582 
    583     ptr->refCounter++;
     590    if (ptr == NULL) {
     591        return ptr;
     592    }
     593
     594    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
     595
     596    if (badMemBlock(memBlock)) {
     597        PS_MEM_ABORT_CORRUPT(memBlock);
     598    }
     599
     600    memBlock->refCounter++;
    584601
    585602    // Did the user ask to be informed about this allocation?
    586     if (ptr->id == p_psMemAllocID) {
    587         p_psMemAllocID += memAllocCallback(ptr);
    588     }
    589 
    590     return vptr;
    591 }
    592 
     603    MUTEX_LOCK(&memBlockListMutex);
     604    if (memBlock->id == p_psMemAllocID) {
     605        p_psMemAllocID += memAllocCallback(memBlock);
     606    }
     607    MUTEX_UNLOCK(&memBlockListMutex);
     608
     609    return ptr;
     610}
     611
     612#if 0
    593613psPtr p_psMemSetRefCounter(psPtr vptr,
    594614                           psReferenceCount count,
     
    609629
    610630    if (badMemBlock(ptr, __func__)) {
     631        (void)p_psMemDecrRefCounter(vptr, filename, lineno);
    611632        memProblemCallback(ptr, file, lineno);
    612633    }
     
    620641    return vptr;
    621642}
     643#endif
    622644
    623645// decrement and return refCounter
    624 psPtr p_psMemDecrRefCounter(psPtr vptr,
     646psPtr p_psMemDecrRefCounter(psPtr ptr,
    625647                            const char *file,
    626648                            psS32 lineno)
    627649{
    628     if (vptr == NULL) {
     650    if (ptr == NULL) {
    629651        return NULL;
    630652    }
    631653
    632     psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
    633 
    634     if (badMemBlock(ptr, __func__) != 0) {
    635         memProblemCallback(ptr, file, lineno);
     654    psMemBlock *memBlock = ((psMemBlock *) ptr) - 1;
     655
     656    if (badMemBlock(memBlock)) {
     657        PS_MEM_ABORT_CORRUPT(memBlock);
    636658        return NULL;
    637659    }
    638660
     661    if (memBlock->refCounter < 1) {
     662        PS_MEM_ABORT(__func__,_("Block %lu, allocated at %s (%s:%d), freed multiple times at %s:%d."),
     663                     (unsigned long)memBlock->id,
     664                     memBlock->func,
     665                     memBlock->file,
     666                     memBlock->lineno,
     667                     file,
     668                     lineno);
     669    }
     670
     671    // if we have multiple references, just decrement the count and return.
     672    if (memBlock->refCounter > 1) {
     673        memBlock->refCounter--;
     674
     675        // Did the user ask to be informed about this deallocation?
     676        MUTEX_LOCK(&memBlockListMutex);
     677        if (memBlock->id == p_psMemFreeID) {
     678            p_psMemFreeID += memFreeCallback(memBlock);
     679        }
     680        MUTEX_UNLOCK(&memBlockListMutex);
     681
     682        return ptr;
     683    }
     684
     685    // we can't invoke freeFunc() while we're holding memBlockListMutex as it
     686    // may invoke psFree() itself
     687    if (memBlock->freeFunc != NULL) {
     688        memBlock->freeFunc(ptr);
     689    }
     690
     691    MUTEX_LOCK(&memBlockListMutex);
     692
    639693    // Did the user ask to be informed about this deallocation?
    640     if (ptr->id == p_psMemFreeID) {
     694    if (memBlock->id == p_psMemFreeID) {
    641695        p_psMemFreeID += memFreeCallback(ptr);
    642696    }
    643697
    644     if (ptr->refCounter > 1) {
    645         ptr->refCounter--;                 // multiple references, just decrement the count.
    646     } else {
    647         if (ptr->freeFunc != NULL) {
    648             ptr->freeFunc(vptr);
    649         }
    650 
    651         MUTEX_LOCK(&memBlockListMutex);
    652 
    653         // cut the memBlock out of the memBlock list
    654         if (ptr->nextBlock != NULL) {
    655             ptr->nextBlock->previousBlock = ptr->previousBlock;
    656         }
    657         if (ptr->previousBlock != NULL) {
    658             ptr->previousBlock->nextBlock = ptr->nextBlock;
    659         }
    660         if (lastMemBlockAllocated == ptr) {
    661             lastMemBlockAllocated = ptr->nextBlock;
    662         }
    663 
    664         MUTEX_UNLOCK(&memBlockListMutex);
    665 
    666         vptr = NULL;                       // since we freed it, make sure we return NULL.
    667     }
    668 
    669     return vptr;
     698    // cut the memBlock out of the memBlock list
     699    if (memBlock->nextBlock != NULL) {
     700        memBlock->nextBlock->previousBlock = memBlock->previousBlock;
     701    }
     702    if (memBlock->previousBlock != NULL) {
     703        memBlock->previousBlock->nextBlock = memBlock->nextBlock;
     704    }
     705    if (lastMemBlockAllocated == memBlock) {
     706        lastMemBlockAllocated = memBlock->nextBlock;
     707    }
     708
     709    MUTEX_UNLOCK(&memBlockListMutex);
     710
     711    // since we freed it, make sure we return NULL.
     712    return NULL;
    670713}
    671714
     
    677720    }
    678721
    679     psMemBlock* PTR = ((psMemBlock* ) ptr) - 1;
    680 
    681     if (badMemBlock(PTR, __func__) != 0) {
    682         memProblemCallback(PTR, __func__, __LINE__);
    683     }
    684 
    685     PTR->freeFunc = freeFunc;
    686 
     722    psMemBlock* memBlock = ((psMemBlock *)ptr) - 1;
     723
     724    if (badMemBlock(memBlock)) {
     725        PS_MEM_ABORT_CORRUPT(memBlock);
     726    }
     727
     728    memBlock->freeFunc = freeFunc;
    687729}
    688730
     
    693735    }
    694736
    695     psMemBlock* PTR = ((psMemBlock* ) ptr) - 1;
    696 
    697     if (badMemBlock(PTR, __func__) != 0) {
    698         memProblemCallback(PTR, __func__, __LINE__);
    699     }
    700 
    701     return PTR->freeFunc;
     737    psMemBlock* memBlock = ((psMemBlock *)ptr) - 1;
     738
     739    if (badMemBlock(memBlock)) {
     740        PS_MEM_ABORT_CORRUPT(memBlock);
     741    }
     742
     743    return memBlock->freeFunc;
    702744}
    703745
     
    705747                    psPtr ptr)
    706748{
    707     //    PS_ASSERT_PTR(ptr, false);
     749    if (!ptr) {
     750        return false;
     751    }
    708752
    709753    switch(type) {
    710754    case PS_DATA_ARRAY:
    711         if ( psMemCheckArray(ptr) )
    712             return true;
    713         else {
    714             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    715                          "Incorrect pointer.  Datatypes do not match.\n");
    716             break;
    717         }
     755        if (psMemCheckArray(ptr)) {
     756            return true;
     757        }
     758        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     759                     "Incorrect pointer.  Datatypes do not match.\n");
     760        break;
    718761    case PS_DATA_BITSET:
    719         if ( psMemCheckBitSet(ptr) )
    720             return true;
    721         else {
    722             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    723                          "Incorrect pointer.  Datatypes do not match.\n");
    724             break;
    725         }
     762        if (psMemCheckBitSet(ptr)) {
     763            return true;
     764        }
     765        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     766                     "Incorrect pointer.  Datatypes do not match.\n");
     767        break;
    726768    case PS_DATA_CUBE:
    727         if ( psMemCheckCube(ptr) )
    728             return true;
    729         else {
    730             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    731                          "Incorrect pointer.  Datatypes do not match.\n");
    732             break;
    733         }
     769        if (psMemCheckCube(ptr)) {
     770            return true;
     771        }
     772        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     773                     "Incorrect pointer.  Datatypes do not match.\n");
     774        break;
    734775    case PS_DATA_FITS:
    735         if ( psMemCheckFits(ptr) )
    736             return true;
    737         else {
    738             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    739                          "Incorrect pointer.  Datatypes do not match.\n");
    740             break;
    741         }
     776        if (psMemCheckFits(ptr)) {
     777            return true;
     778        }
     779        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     780                     "Incorrect pointer.  Datatypes do not match.\n");
     781        break;
    742782    case PS_DATA_HASH:
    743         if ( psMemCheckHash(ptr) )
    744             return true;
    745         else {
    746             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    747                          "Incorrect pointer.  Datatypes do not match.\n");
    748             break;
    749         }
     783        if (psMemCheckHash(ptr)) {
     784            return true;
     785        }
     786        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     787                     "Incorrect pointer.  Datatypes do not match.\n");
     788        break;
    750789    case PS_DATA_HISTOGRAM:
    751         if ( psMemCheckHistogram(ptr) )
    752             return true;
    753         else {
    754             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    755                          "Incorrect pointer.  Datatypes do not match.\n");
    756             break;
    757         }
     790        if (psMemCheckHistogram(ptr)) {
     791            return true;
     792        }
     793        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     794                     "Incorrect pointer.  Datatypes do not match.\n");
     795        break;
    758796    case PS_DATA_IMAGE:
    759         if ( psMemCheckImage(ptr) )
    760             return true;
    761         else {
    762             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    763                          "Incorrect pointer.  Datatypes do not match.\n");
    764             break;
    765         }
     797        if (psMemCheckImage(ptr)) {
     798            return true;
     799        }
     800        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     801                     "Incorrect pointer.  Datatypes do not match.\n");
     802        break;
    766803    case PS_DATA_KERNEL:
    767         if ( psMemCheckKernel(ptr) )
    768             return true;
    769         else {
    770             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    771                          "Incorrect pointer.  Datatypes do not match.\n");
    772             break;
    773         }
     804        if (psMemCheckKernel(ptr)) {
     805            return true;
     806        }
     807        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     808                     "Incorrect pointer.  Datatypes do not match.\n");
     809        break;
    774810    case PS_DATA_LINE:
    775         if ( psMemCheckLine(ptr) )
    776             return true;
    777         else {
    778             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    779                          "Incorrect pointer.  Datatypes do not match.\n");
    780             break;
    781         }
     811        if (psMemCheckLine(ptr)) {
     812            return true;
     813        }
     814        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     815                     "Incorrect pointer.  Datatypes do not match.\n");
     816        break;
    782817    case PS_DATA_LIST:
    783         if ( psMemCheckList(ptr) )
    784             return true;
    785         else {
    786             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    787                          "Incorrect pointer.  Datatypes do not match.\n");
    788             break;
    789         }
     818        if (psMemCheckList(ptr)) {
     819            return true;
     820        }
     821        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     822                     "Incorrect pointer.  Datatypes do not match.\n");
     823        break;
    790824    case PS_DATA_LOOKUPTABLE:
    791         if ( psMemCheckLookupTable(ptr) )
    792             return true;
    793         else {
    794             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    795                          "Incorrect pointer.  Datatypes do not match.\n");
    796             break;
    797         }
     825        if (psMemCheckLookupTable(ptr)) {
     826            return true;
     827        }
     828        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     829                     "Incorrect pointer.  Datatypes do not match.\n");
     830        break;
    798831    case PS_DATA_METADATA:
    799         if ( psMemCheckMetadata(ptr) )
    800             return true;
    801         else {
    802             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    803                          "Incorrect pointer.  Datatypes do not match.\n");
    804             break;
    805         }
     832        if (psMemCheckMetadata(ptr)) {
     833            return true;
     834        }
     835        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     836                     "Incorrect pointer.  Datatypes do not match.\n");
     837        break;
    806838    case PS_DATA_METADATAITEM:
    807         if ( psMemCheckMetadataItem(ptr) )
    808             return true;
    809         else {
    810             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    811                          "Incorrect pointer.  Datatypes do not match.\n");
    812             break;
    813         }
     839        if (psMemCheckMetadataItem(ptr)) {
     840            return true;
     841        }
     842        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     843                     "Incorrect pointer.  Datatypes do not match.\n");
     844        break;
    814845    case PS_DATA_MINIMIZATION:
    815         if ( psMemCheckMinimization(ptr) )
    816             return true;
    817         else {
    818             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    819                          "Incorrect pointer.  Datatypes do not match.\n");
    820             break;
    821         }
     846        if (psMemCheckMinimization(ptr)) {
     847            return true;
     848        }
     849        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     850                     "Incorrect pointer.  Datatypes do not match.\n");
     851        break;
    822852    case PS_DATA_PIXELS:
    823         if ( psMemCheckPixels(ptr) )
    824             return true;
    825         else {
    826             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    827                          "Incorrect pointer.  Datatypes do not match.\n");
    828             break;
    829         }
     853        if (psMemCheckPixels(ptr)) {
     854            return true;
     855        }
     856        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     857                     "Incorrect pointer.  Datatypes do not match.\n");
     858        break;
    830859    case PS_DATA_PLANE:
    831         if ( psMemCheckPlane(ptr) )
    832             return true;
    833         else {
    834             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    835                          "Incorrect pointer.  Datatypes do not match.\n");
    836             break;
    837         }
     860        if (psMemCheckPlane(ptr)) {
     861            return true;
     862        }
     863        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     864                     "Incorrect pointer.  Datatypes do not match.\n");
     865        break;
    838866    case PS_DATA_PLANEDISTORT:
    839         if ( psMemCheckPlaneDistort(ptr) )
    840             return true;
    841         else {
    842             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    843                          "Incorrect pointer.  Datatypes do not match.\n");
    844             break;
    845         }
     867        if (psMemCheckPlaneDistort(ptr)) {
     868            return true;
     869        }
     870        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     871                     "Incorrect pointer.  Datatypes do not match.\n");
     872        break;
    846873    case PS_DATA_PLANETRANSFORM:
    847         if ( psMemCheckPlaneTransform(ptr) )
    848             return true;
    849         else {
    850             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    851                          "Incorrect pointer.  Datatypes do not match.\n");
    852             break;
    853         }
     874        if (psMemCheckPlaneTransform(ptr)) {
     875            return true;
     876        }
     877        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     878                     "Incorrect pointer.  Datatypes do not match.\n");
     879        break;
    854880    case PS_DATA_POLYNOMIAL1D:
    855         if ( psMemCheckPolynomial1D(ptr) )
    856             return true;
    857         else {
    858             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    859                          "Incorrect pointer.  Datatypes do not match.\n");
    860             break;
    861         }
     881        if (psMemCheckPolynomial1D(ptr)) {
     882            return true;
     883        }
     884        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     885                     "Incorrect pointer.  Datatypes do not match.\n");
     886        break;
    862887    case PS_DATA_POLYNOMIAL2D:
    863         if ( psMemCheckPolynomial2D(ptr) )
    864             return true;
    865         else {
    866             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    867                          "Incorrect pointer.  Datatypes do not match.\n");
    868             break;
    869         }
     888        if (psMemCheckPolynomial2D(ptr)) {
     889            return true;
     890        }
     891        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     892                     "Incorrect pointer.  Datatypes do not match.\n");
     893        break;
    870894    case PS_DATA_POLYNOMIAL3D:
    871         if ( psMemCheckPolynomial3D(ptr) )
    872             return true;
    873         else {
    874             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    875                          "Incorrect pointer.  Datatypes do not match.\n");
    876             break;
    877         }
     895        if (psMemCheckPolynomial3D(ptr)) {
     896            return true;
     897        }
     898        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     899                     "Incorrect pointer.  Datatypes do not match.\n");
     900        break;
    878901    case PS_DATA_POLYNOMIAL4D:
    879         if ( psMemCheckPolynomial4D(ptr) )
    880             return true;
    881         else {
    882             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    883                          "Incorrect pointer.  Datatypes do not match.\n");
    884             break;
    885         }
     902        if (psMemCheckPolynomial4D(ptr)) {
     903            return true;
     904        }
     905        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     906                     "Incorrect pointer.  Datatypes do not match.\n");
     907        break;
    886908    case PS_DATA_PROJECTION:
    887         if ( psMemCheckProjection(ptr) )
    888             return true;
    889         else {
    890             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    891                          "Incorrect pointer.  Datatypes do not match.\n");
    892             break;
    893         }
     909        if (psMemCheckProjection(ptr)) {
     910            return true;
     911        }
     912        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     913                     "Incorrect pointer.  Datatypes do not match.\n");
     914        break;
    894915    case PS_DATA_REGION:
    895         if ( psMemCheckRegion(ptr) )
    896             return true;
    897         else {
    898             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    899                          "Incorrect pointer.  Datatypes do not match.\n");
    900             break;
    901         }
     916        if (psMemCheckRegion(ptr)) {
     917            return true;
     918        }
     919        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     920                     "Incorrect pointer.  Datatypes do not match.\n");
     921        break;
    902922    case PS_DATA_SCALAR:
    903         if ( psMemCheckScalar(ptr) )
    904             return true;
    905         else {
    906             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    907                          "Incorrect pointer.  Datatypes do not match.\n");
    908             break;
    909         }
     923        if (psMemCheckScalar(ptr)) {
     924            return true;
     925        }
     926        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     927                     "Incorrect pointer.  Datatypes do not match.\n");
     928        break;
    910929    case PS_DATA_SPHERE:
    911         if ( psMemCheckSphere(ptr) )
    912             return true;
    913         else {
    914             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    915                          "Incorrect pointer.  Datatypes do not match.\n");
    916             break;
    917         }
     930        if (psMemCheckSphere(ptr)) {
     931            return true;
     932        }
     933        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     934                     "Incorrect pointer.  Datatypes do not match.\n");
     935        break;
    918936    case PS_DATA_SPHEREROT:
    919         if ( psMemCheckSphereRot(ptr) )
    920             return true;
    921         else {
    922             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    923                          "Incorrect pointer.  Datatypes do not match.\n");
    924             break;
    925         }
     937        if (psMemCheckSphereRot(ptr)) {
     938            return true;
     939        }
     940        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     941                     "Incorrect pointer.  Datatypes do not match.\n");
     942        break;
    926943    case PS_DATA_SPLINE1D:
    927         if ( psMemCheckSpline1D(ptr) )
    928             return true;
    929         else {
    930             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    931                          "Incorrect pointer.  Datatypes do not match.\n");
    932             break;
    933         }
     944        if (psMemCheckSpline1D(ptr)) {
     945            return true;
     946        }
     947        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     948                     "Incorrect pointer.  Datatypes do not match.\n");
     949        break;
    934950    case PS_DATA_STATS:
    935         if ( psMemCheckStats(ptr) )
    936             return true;
    937         else {
    938             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    939                          "Incorrect pointer.  Datatypes do not match.\n");
    940             break;
    941         }
     951        if (psMemCheckStats(ptr)) {
     952            return true;
     953        }
     954        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     955                     "Incorrect pointer.  Datatypes do not match.\n");
     956        break;
    942957    case PS_DATA_STRING:
    943         if ( psMemCheckString(ptr) )
    944             return true;
    945         else {
    946             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    947                          "Incorrect pointer.  Datatypes do not match.\n");
    948             break;
    949         }
     958        if (psMemCheckString(ptr)) {
     959            return true;
     960        }
     961        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     962                     "Incorrect pointer.  Datatypes do not match.\n");
     963        break;
    950964    case PS_DATA_TIME:
    951         if ( psMemCheckTime(ptr) )
    952             return true;
    953         else {
    954             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    955                          "Incorrect pointer.  Datatypes do not match.\n");
    956             break;
    957         }
     965        if (psMemCheckTime(ptr)) {
     966            return true;
     967        }
     968        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     969                     "Incorrect pointer.  Datatypes do not match.\n");
     970        break;
    958971    case PS_DATA_VECTOR:
    959         if ( psMemCheckVector(ptr) )
    960             return true;
    961         else {
    962             PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
    963                          "Incorrect pointer.  Datatypes do not match.\n");
    964             break;
    965         }
     972        if (psMemCheckVector(ptr)) {
     973            return true;
     974        }
     975        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_VALUE, false,
     976                     "Incorrect pointer.  Datatypes do not match.\n");
     977        break;
    966978    default:
    967979        PS_MEM_ERROR(PS_ERR_BAD_PARAMETER_TYPE, true,
    968980                     "Invalid datatype specified.\n");
    969981    }
     982
    970983    return false;
    971984}
     
    973986bool psMemSetThreadSafety(bool safe)
    974987{
    975     bool out = safeThreads;
     988    MUTEX_LOCK(&memBlockListMutex);
     989
     990    bool oldState = safeThreads;
    976991    safeThreads = safe;
    977     return out;
     992
     993    MUTEX_UNLOCK(&memBlockListMutex);
     994
     995    return oldState;
    978996}
    979997
    980998bool psMemGetThreadSafety(void)
    981999{
    982     return safeThreads;
    983 }
    984 
    985 bool p_psMemGetPersistent(psPtr vptr)
    986 {
    987     if (vptr == NULL) {
     1000    MUTEX_LOCK(&memBlockListMutex);
     1001
     1002    bool oldState = safeThreads;
     1003
     1004    MUTEX_UNLOCK(&memBlockListMutex);
     1005
     1006    return oldState;
     1007}
     1008
     1009bool p_psMemGetPersistent(psPtr ptr)
     1010{
     1011    if (ptr == NULL) {
    9881012        return NULL;
    9891013    }
    9901014
    991     psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
    992 
    993     if (badMemBlock(ptr, __func__) != 0) {
    994         memProblemCallback(ptr, __func__, __LINE__);
    995     }
    996 
    997     return ptr->persistent;
    998 }
    999 
    1000 void p_psMemSetPersistent(psPtr vptr,
     1015    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
     1016
     1017    if (badMemBlock(memBlock)) {
     1018        PS_MEM_ABORT_CORRUPT(memBlock);
     1019    }
     1020
     1021    return memBlock->persistent;
     1022}
     1023
     1024void p_psMemSetPersistent(psPtr ptr,
    10011025                          bool value)
    10021026{
    1003     if (vptr == NULL) {
     1027    if (ptr == NULL) {
    10041028        return;
    10051029    }
    10061030
    1007     psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
    1008 
    1009     if (badMemBlock(ptr, __func__) != 0) {
    1010         memProblemCallback(ptr, __func__, __LINE__);
    1011     }
    1012 
    1013     ptr->persistent = value;
     1031    psMemBlock* memBlock = ((psMemBlock *) ptr) - 1;
     1032
     1033    if (badMemBlock(memBlock)) {
     1034        PS_MEM_ABORT_CORRUPT(memBlock);
     1035    }
     1036
     1037    memBlock->persistent = value;
    10141038}
    10151039
  • branches/jch-memory/psLib/src/sys/psMemory.h

    r10896 r10899  
    1212 *  @ingroup MemoryManagement
    1313 *
    14  *  @version $Revision: 1.61.2.2 $ $Name: not supported by cvs2svn $
    15  *  @date $Date: 2007-01-03 22:25:33 $
     14 *  @version $Revision: 1.61.2.3 $ $Name: not supported by cvs2svn $
     15 *  @date $Date: 2007-01-04 21:09:32 $
    1616 *
    1717 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    7272    size_t userMemorySize;             ///< the size of the user-portion of the memory block
    7373    const psMemId id;                  ///< a unique ID for this allocation
     74    const pthread_t tid;               ///< set from pthread_self();
    7475    const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
    7576    const unsigned int lineno;         ///< set from __LINE__ in e.g. p_psAlloc
     77    const char *func;                  ///< set from __func__
    7678    psReferenceCount refCounter;       ///< how many times pointer is referenced
    7779    bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
     
    137139psPtr p_psAlloc(
    138140    size_t size,                       ///< Size required
    139     const char *filename,              ///< File of call
    140     unsigned int lineno                ///< Line number of call
     141    const char *filename,              ///< File of caller
     142    unsigned int lineno,               ///< Line number of caller
     143    const char *func                   ///< Function name of caller
    141144);
    142145
    143146/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
    144147#ifndef SWIG
    145 #define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
     148#define psAlloc(size) \
     149p_psAlloc(size, __FILE__, __LINE__, __func__)
    146150#endif // ! SWIG
    147151
     
    256260    psPtr ptr,                         ///< Pointer to re-allocate
    257261    size_t size,                       ///< Size required
    258     const char *filename,              ///< File of call
    259     unsigned int lineno                ///< Line number of call
     262    const char *filename,              ///< File of caller
     263    unsigned int lineno,               ///< Line number of caller
     264    const char *func                   ///< Function name of caller
    260265);
    261266
    262267/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
    263268#ifndef SWIG
    264 #define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
     269#define psRealloc(ptr, size) \
     270p_psRealloc(ptr, size, __FILE__, __LINE__, __func__)
    265271#endif // ! SWIG
    266272
     
    276282);
    277283#else // #ifdef DOXYGEN
    278 void p_psFree(
    279     psPtr ptr,                         ///< Pointer to free
    280     const char *filename,              ///< File of call
    281     unsigned int lineno                ///< Line number of call
    282 );
    283284
    284285/// Free memory.  psFree sends file and line number to p_psFree.
    285286#ifndef SWIG
    286 //#define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); *(void**)&(ptr) = NULL; }
    287 #define psFree(ptr) { p_psFree((psPtr)ptr, __FILE__, __LINE__); }
     287//#define psFree(ptr) { p_psMemDecrRefCounter((psPtr)ptr, __FILE__, __LINE__); *(void**)&(ptr) = NULL; }
     288#define psFree(ptr) { p_psMemDecrRefCounter((psPtr)ptr, __FILE__, __LINE__); }
    288289#endif // ! SWIG
    289290
     
    379380#endif // !DOXYGEN
    380381
     382#if 0 // psMemSetRefCounter
    381383/** Set reference counter and return the pointer
    382384 *
     
    404406
    405407#endif // !DOXYGEN
     408#endif // psMemSetRefCounter
    406409
    407410/** Set callback for problems.
Note: See TracChangeset for help on using the changeset viewer.