IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 474


Ignore:
Timestamp:
Apr 19, 2004, 5:10:32 PM (22 years ago)
Author:
desonia
Message:

* empty log message *

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/sysUtils/psMemory.c

    r473 r474  
    88 *  @author Robert Lupton, Princeton University
    99 *
    10  *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-04-20 03:08:35 $
     10 *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2004-04-20 03:10:31 $
    1212 *
    1313 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3939static void *memExhaustedCallbackDefault(size_t size)
    4040{
    41   return NULL;
     41    return NULL;
    4242}
    4343
     
    4646psMemExhaustedCallback psMemExhaustedSetCallback(psMemExhaustedCallback func)
    4747{
    48   psMemExhaustedCallback old = memExhaustedCallback;
    49 
    50   if (func != NULL)
    51     {
    52       memExhaustedCallback = func;
    53     }
    54   else
    55     {
    56       memExhaustedCallback = memExhaustedCallbackDefault;
    57     }
    58 
    59   return old;
     48    psMemExhaustedCallback old = memExhaustedCallback;
     49
     50    if (func != NULL) {
     51        memExhaustedCallback = func;
     52    } else {
     53        memExhaustedCallback = memExhaustedCallbackDefault;
     54    }
     55
     56    return old;
    6057}
    6158
     
    6360                                      const char *file, int lineno)
    6461{
    65   checkMemBlock(ptr, __func__);
    66 
    67   if (ptr->refCounter <= 0)
    68     {
    69       psError(__func__,
    70               "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
    71               ptr->id, ptr->file, ptr->lineno, file, lineno);
    72     }
    73   else if (ptr->refCounter > 1)
    74     {
    75       psError(__func__,
    76               "Block %ld allocated at %s:%d freed while still referenced at %s:%d\n",
    77               ptr->id, ptr->file, ptr->lineno, file, lineno);
    78     }
    79 
    80   if (lineno > 0)
    81     {
    82       psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
     62    checkMemBlock(ptr, __func__);
     63
     64    if (ptr->refCounter <= 0) {
     65        psError(__func__,
     66                "Block %ld allocated at %s:%d freed more than once at %s:%d\n",
     67                ptr->id, ptr->file, ptr->lineno, file, lineno);
     68    } else if (ptr->refCounter > 1) {
     69        psError(__func__,
     70                "Block %ld allocated at %s:%d freed while still referenced at %s:%d\n",
     71                ptr->id, ptr->file, ptr->lineno, file, lineno);
     72    }
     73
     74    if (lineno > 0) {
     75        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
    8376    }
    8477}
     
    8780psMemProblemCallback psMemProblemSetCallback(psMemProblemCallback func)
    8881{
    89   psMemProblemCallback old = memProblemCallback;
    90 
    91   if (func != NULL)
    92     {
    93       memProblemCallback = func;
    94     }
    95   else
    96     {
    97       memProblemCallback = memProblemCallbackDefault;
    98     }
    99 
    100   return old;
     82    psMemProblemCallback old = memProblemCallback;
     83
     84    if (func != NULL) {
     85        memProblemCallback = func;
     86    } else {
     87        memProblemCallback = memProblemCallbackDefault;
     88    }
     89
     90    return old;
    10191}
    10292/*
     
    110100long psMemSetAllocateID(long id) // set p_psMemAllocateID to id
    111101{
    112   long old = p_psMemAllocateID;
    113   p_psMemAllocateID = id;
    114 
    115   return old;
     102    long old = p_psMemAllocateID;
     103    p_psMemAllocateID = id;
     104
     105    return old;
    116106}
    117107
    118108long psMemSetFreeID(long id)  // set p_psMemFreeID to id
    119109{
    120   long old = p_psMemFreeID;
    121   p_psMemFreeID = id;
    122 
    123   return old;
     110    long old = p_psMemFreeID;
     111    p_psMemFreeID = id;
     112
     113    return old;
    124114}
    125115
     
    132122static long memAllocateCallbackDefault(const psMemBlock *ptr)
    133123{
    134   static int incr = 0;  // "p_psMemAllocateID += incr"
    135 
    136   return incr;
     124    static int incr = 0;  // "p_psMemAllocateID += incr"
     125
     126    return incr;
    137127}
    138128
    139129static long memFreeCallbackDefault(const psMemBlock *ptr)
    140130{
    141   static int incr = 0;  // "p_psMemFreeID += incr"
    142 
    143   return incr;
     131    static int incr = 0;  // "p_psMemFreeID += incr"
     132
     133    return incr;
    144134}
    145135
     
    152142psMemAllocateCallback psMemAllocateSetCallback(psMemAllocateCallback func)
    153143{
    154   psMemFreeCallback old = memAllocateCallback;
    155 
    156   if (func != NULL)
    157     {
    158       memAllocateCallback =  func;
    159     }
    160   else
    161     {
    162       memAllocateCallback = memAllocateCallbackDefault;
    163     }
    164 
    165   return old;
     144    psMemFreeCallback old = memAllocateCallback;
     145
     146    if (func != NULL) {
     147        memAllocateCallback =  func;
     148    } else {
     149        memAllocateCallback = memAllocateCallbackDefault;
     150    }
     151
     152    return old;
    166153}
    167154
    168155psMemFreeCallback psMemFreeSetCallback(psMemFreeCallback func)
    169156{
    170   psMemFreeCallback old = memFreeCallback;
    171 
    172   if (func != NULL)
    173     {
    174       memFreeCallback = func;
    175     }
    176   else
    177     {
    178       memFreeCallback = memFreeCallbackDefault;
    179     }
    180 
    181   return old;
     157    psMemFreeCallback old = memFreeCallback;
     158
     159    if (func != NULL) {
     160        memFreeCallback = func;
     161    } else {
     162        memFreeCallback = memFreeCallbackDefault;
     163    }
     164
     165    return old;
    182166}
    183167
     
    187171int psMemGetId(void)
    188172{
    189   return memid + 1;
     173    return memid + 1;
    190174}
    191175
     
    201185              const char* funcName)
    202186{
    203   // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
    204   // we shouldn't call such things as p_psAlloc/p_psFree here.
    205 
    206   if (m == NULL)
    207     {
    208       psError(funcName,"Memory Corruption: NULL memory block found.");
    209       return(1);
    210     }
    211 
    212   if (!ALIGNED(m))
    213     {
    214       psError(funcName, "psMemCheckCorruption: non-aligned memory block");
    215       return(1);
    216     }
    217 
    218   if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC)
    219     {
    220       psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted", m->id);
    221       return(1);
    222     }
    223 
    224   return(0);
     187    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
     188    // we shouldn't call such things as p_psAlloc/p_psFree here.
     189
     190    if (m == NULL) {
     191        psError(funcName,"Memory Corruption: NULL memory block found.");
     192        return(1);
     193    }
     194
     195    if (!ALIGNED(m)) {
     196        psError(funcName, "psMemCheckCorruption: non-aligned memory block");
     197        return(1);
     198    }
     199
     200    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
     201        psError(funcName, "psMemCheckCorruption: memory block %ld is corrupted", m->id);
     202        return(1);
     203    }
     204
     205    return(0);
    225206}
    226207
    227208int psMemCheckCorruption(int abort_on_error)
    228209{
    229   int nbad = 0;                       // number of bad blocks
    230 
    231   // get exclusive access to the memBlock list to avoid it changing on us while we use it.
    232   pthread_mutex_lock(&memBlockListMutex);
    233 
    234   for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock)
    235     {
    236       if (checkMemBlock(iter, __func__))
    237         {
    238           nbad++;
    239 
    240           memProblemCallback(iter, __func__, __LINE__);
    241 
    242           if (abort_on_error)
    243             {
    244               // release the lock on the memblock list
    245               pthread_mutex_unlock(&memBlockListMutex);
    246               psAbort(__func__, "Detected memory corruption");
    247               return nbad;
    248             }
    249         }
    250     }
    251 
    252   // release the lock on the memblock list
    253   pthread_mutex_unlock(&memBlockListMutex);
    254   return nbad;
     210    int nbad = 0;                       // number of bad blocks
     211
     212    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
     213    pthread_mutex_lock(&memBlockListMutex);
     214
     215    for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) {
     216        if (checkMemBlock(iter, __func__)) {
     217            nbad++;
     218
     219            memProblemCallback(iter, __func__, __LINE__);
     220
     221            if (abort_on_error) {
     222                // release the lock on the memblock list
     223                pthread_mutex_unlock(&memBlockListMutex);
     224                psAbort(__func__, "Detected memory corruption");
     225                return nbad;
     226            }
     227        }
     228    }
     229
     230    // release the lock on the memblock list
     231    pthread_mutex_unlock(&memBlockListMutex);
     232    return nbad;
    255233}
    256234
    257235void *p_psAlloc(size_t size, const char *file, int lineno)
    258236{
    259   psMemBlock *ptr = malloc(sizeof(psMemBlock) + size);
    260 
    261   if (ptr == NULL)
    262     {
    263       ptr = memExhaustedCallback(size);
    264       if (ptr == NULL)
    265         {
    266           psAbort(__func__, "Failed to allocate %ld bytes at %s:%d",
    267                   size, file, lineno);
    268         }
    269     }
    270 
    271   *(unsigned long*)&ptr->id = ++memid;
    272   ptr->file = file;
    273   *(unsigned int*)&ptr->lineno = lineno;
    274   ptr->startblock = P_PS_MEMMAGIC;
    275   ptr->endblock = P_PS_MEMMAGIC;
    276   ptr->refCounter = 1;                // one user so far
    277 
    278   // need exclusive access of the memory block list now...
    279   pthread_mutex_lock(&memBlockListMutex);
    280 
    281   // insert the new block to the front of the memBlock linked-list
    282   ptr->previousBlock = NULL;
    283   ptr->nextBlock = lastMemBlockAllocated;
    284   if (ptr->nextBlock != NULL)
    285     {
    286       ptr->nextBlock->previousBlock = ptr;
    287     }
    288   lastMemBlockAllocated = ptr;
    289 
    290   pthread_mutex_unlock(&memBlockListMutex);
    291 
    292   //  Did the user ask to be informed about this allocation?
    293   if (ptr->id == p_psMemAllocateID)
    294     {
    295       p_psMemAllocateID += memAllocateCallback(ptr);
    296     }
    297 
    298   // And return the user the memory that they allocated
    299   return ptr + 1;   // user memory
     237    psMemBlock *ptr = malloc(sizeof(psMemBlock) + size);
     238
     239    if (ptr == NULL) {
     240        ptr = memExhaustedCallback(size);
     241        if (ptr == NULL) {
     242            psAbort(__func__, "Failed to allocate %ld bytes at %s:%d",
     243                    size, file, lineno);
     244        }
     245    }
     246
     247    *(unsigned long*)&ptr->id = ++memid;
     248    ptr->file = file;
     249    *(unsigned int*)&ptr->lineno = lineno;
     250    ptr->startblock = P_PS_MEMMAGIC;
     251    ptr->endblock = P_PS_MEMMAGIC;
     252    ptr->refCounter = 1;                // one user so far
     253
     254    // need exclusive access of the memory block list now...
     255    pthread_mutex_lock(&memBlockListMutex);
     256
     257    // insert the new block to the front of the memBlock linked-list
     258    ptr->previousBlock = NULL;
     259    ptr->nextBlock = lastMemBlockAllocated;
     260    if (ptr->nextBlock != NULL) {
     261        ptr->nextBlock->previousBlock = ptr;
     262    }
     263    lastMemBlockAllocated = ptr;
     264
     265    pthread_mutex_unlock(&memBlockListMutex);
     266
     267    //  Did the user ask to be informed about this allocation?
     268    if (ptr->id == p_psMemAllocateID) {
     269        p_psMemAllocateID += memAllocateCallback(ptr);
     270    }
     271
     272    // And return the user the memory that they allocated
     273    return ptr + 1;   // user memory
    300274}
    301275
    302276void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
    303277{
    304   if (vptr == NULL)
    305     {
    306       return p_psAlloc(size, file, lineno);
    307     }
    308   else
    309     {
    310       psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    311 
    312       pthread_mutex_lock(&memBlockListMutex);
    313 
    314       ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size);
    315 
    316       // the block location may have changed, so fix the linked list addresses.
    317       if (ptr->nextBlock != NULL)
    318         {
    319           ptr->nextBlock->previousBlock = ptr;
    320         }
    321       if (ptr->previousBlock != NULL)
    322         {
    323           ptr->previousBlock->nextBlock = ptr;
    324         }
    325 
    326       pthread_mutex_unlock(&memBlockListMutex);
    327 
    328       return ptr + 1;   // usr memory
     278    if (vptr == NULL) {
     279        return p_psAlloc(size, file, lineno);
     280    } else {
     281        psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
     282
     283        pthread_mutex_lock(&memBlockListMutex);
     284
     285        ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size);
     286
     287        // the block location may have changed, so fix the linked list addresses.
     288        if (ptr->nextBlock != NULL) {
     289            ptr->nextBlock->previousBlock = ptr;
     290        }
     291        if (ptr->previousBlock != NULL) {
     292            ptr->previousBlock->nextBlock = ptr;
     293        }
     294
     295        pthread_mutex_unlock(&memBlockListMutex);
     296
     297        return ptr + 1;   // usr memory
    329298    }
    330299}
     
    332301void p_psFree(void *vptr, const char *file, int lineno)
    333302{
    334   if (vptr == NULL)
    335     {
    336       return;
    337     }
    338 
    339   psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    340 
    341   // Did the user ask to be informed about this deallocation?
    342   if (ptr->id == p_psMemFreeID)
    343     {
    344       p_psMemFreeID += memFreeCallback(ptr);
    345     }
    346 
    347   if (checkMemBlock(ptr, "psFree") != 0)
    348     {
    349       memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it
    350     }
    351   else
    352     {
    353       if (ptr->refCounter > 1)
    354         {
    355           psError(__func__,"The buffer being freed is referenced elsewhere. "
    356                   "Buffer's reference count was decremented instead.");
    357           ptr->refCounter--;
    358           memProblemCallback(ptr, file, lineno);
    359         }
    360       else
    361         {
    362 
    363           // cut the memBlock out of the memBlock list
    364           pthread_mutex_lock(&memBlockListMutex);
    365           if (ptr->nextBlock != NULL)
    366             {
    367               ptr->nextBlock->previousBlock = ptr->previousBlock;
    368             }
    369           if (ptr->previousBlock != NULL)
    370             {
    371               ptr->previousBlock->nextBlock = ptr->nextBlock;
    372             }
    373           if (lastMemBlockAllocated == ptr)
    374             {
    375               lastMemBlockAllocated = ptr->nextBlock;
    376             }
    377 
    378           pthread_mutex_unlock(&memBlockListMutex);
    379 
    380           free(ptr);
     303    if (vptr == NULL) {
     304        return;
     305    }
     306
     307    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
     308
     309    // Did the user ask to be informed about this deallocation?
     310    if (ptr->id == p_psMemFreeID) {
     311        p_psMemFreeID += memFreeCallback(ptr);
     312    }
     313
     314    if (checkMemBlock(ptr, "psFree") != 0) {
     315        memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it
     316    } else {
     317        if (ptr->refCounter > 1) {
     318            psError(__func__,"The buffer being freed is referenced elsewhere. "
     319                    "Buffer's reference count was decremented instead.");
     320            ptr->refCounter--;
     321            memProblemCallback(ptr, file, lineno);
     322        } else {
     323
     324            // cut the memBlock out of the memBlock list
     325            pthread_mutex_lock(&memBlockListMutex);
     326            if (ptr->nextBlock != NULL) {
     327                ptr->nextBlock->previousBlock = ptr->previousBlock;
     328            }
     329            if (ptr->previousBlock != NULL) {
     330                ptr->previousBlock->nextBlock = ptr->nextBlock;
     331            }
     332            if (lastMemBlockAllocated == ptr) {
     333                lastMemBlockAllocated = ptr->nextBlock;
     334            }
     335
     336            pthread_mutex_unlock(&memBlockListMutex);
     337
     338            free(ptr);
    381339        }
    382340    }
     
    387345 */
    388346int psMemCheckLeaks(
    389   int id0,                            // don't list blocks with id < id0
    390   psMemBlock ***arr,                  // pointer to array of pointers to leaked blocks, or NULL
    391   FILE *fd)                           // print list of leaks to fd (or NULL)
    392 {
    393   int nleak = 0;
    394   int j = 0;
    395 
    396   pthread_mutex_lock(&memBlockListMutex);
    397 
    398   for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock)
    399     {
    400       if ( (iter->refCounter > 0) && (iter->id >= id0) )
    401         {
    402           nleak++;
    403 
    404           if (fd != NULL)
    405             {
    406               if (nleak == 1)
    407                 {
    408                   fprintf(fd, "   %20s:line ID\n", "file");
     347    int id0,                            // don't list blocks with id < id0
     348    psMemBlock ***arr,                  // pointer to array of pointers to leaked blocks, or NULL
     349    FILE *fd)                           // print list of leaks to fd (or NULL)
     350{
     351    int nleak = 0;
     352    int j = 0;
     353
     354    pthread_mutex_lock(&memBlockListMutex);
     355
     356    for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock)
     357    {
     358        if ( (iter->refCounter > 0) && (iter->id >= id0) ) {
     359            nleak++;
     360
     361            if (fd != NULL) {
     362                if (nleak == 1) {
     363                    fprintf(fd, "   %20s:line ID\n", "file");
    409364                }
    410365
    411               fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
    412             }
    413         }
    414     }
    415 
    416   pthread_mutex_unlock(&memBlockListMutex);
    417 
    418   if (nleak == 0 || arr == NULL)
    419     {
    420       return nleak;
    421     }
    422 
    423   p_psFree(*arr,__FILE__, __LINE__);  // Don't generate a memory leak!
    424 
    425   *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
    426 
    427   pthread_mutex_lock(&memBlockListMutex);
    428 
    429   for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock)
    430     {
    431       if ( (iter->refCounter > 0) && (iter->id >= id0) )
    432         {
    433           (*arr)[j++] = iter;
    434           if (j == nleak)
    435             { // found them all
    436               break;
    437             }
    438         }
    439     }
    440 
    441   pthread_mutex_unlock(&memBlockListMutex);
    442 
    443   return nleak;
     366                fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
     367            }
     368        }
     369    }
     370
     371    pthread_mutex_unlock(&memBlockListMutex);
     372
     373    if (nleak == 0 || arr == NULL)
     374    {
     375        return nleak;
     376    }
     377
     378    p_psFree(*arr,__FILE__, __LINE__);  // Don't generate a memory leak!
     379
     380    *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__);
     381
     382    pthread_mutex_lock(&memBlockListMutex);
     383
     384    for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock)
     385    {
     386        if ( (iter->refCounter > 0) && (iter->id >= id0) ) {
     387            (*arr)[j++] = iter;
     388            if (j == nleak) { // found them all
     389                break;
     390            }
     391        }
     392    }
     393
     394    pthread_mutex_unlock(&memBlockListMutex);
     395
     396    return nleak;
    444397}
    445398
     
    449402int psMemGetRefCounter(void *vptr) // return refCounter
    450403{
    451   psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    452 
    453   if (checkMemBlock(ptr, __func__) != 0)
    454     {
    455       memProblemCallback(ptr, __func__, __LINE__);
    456     }
    457 
    458   return ptr->refCounter;
     404    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
     405
     406    if (checkMemBlock(ptr, __func__) != 0)
     407    {
     408        memProblemCallback(ptr, __func__, __LINE__);
     409    }
     410
     411    return ptr->refCounter;
    459412}
    460413
    461414void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
    462415{
    463   if (vptr == NULL)
    464     {
    465       return vptr;
    466     }
    467 
    468   psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    469 
    470   if (checkMemBlock(ptr, __func__))
    471     {
    472       memProblemCallback(ptr, __func__, __LINE__);
    473     }
    474 
    475   ptr->refCounter++;
    476 
    477   return vptr;
     416    if (vptr == NULL)
     417    {
     418        return vptr;
     419    }
     420
     421    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
     422
     423    if (checkMemBlock(ptr, __func__))
     424    {
     425        memProblemCallback(ptr, __func__, __LINE__);
     426    }
     427
     428    ptr->refCounter++;
     429
     430    return vptr;
    478431}
    479432
    480433void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
    481434{
    482   if (vptr == NULL)
    483     {
    484       return vptr;
    485     }
    486 
    487   psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
    488 
    489   if (checkMemBlock(ptr, __func__))
    490     {
    491       memProblemCallback(ptr, __func__, __LINE__);
    492     }
    493 
    494   ptr->refCounter--;
    495 
    496   return vptr;
    497 }
     435    if (vptr == NULL)
     436    {
     437        return vptr;
     438    }
     439
     440    psMemBlock *ptr = ((psMemBlock *)vptr) - 1;
     441
     442    if (checkMemBlock(ptr, __func__))
     443    {
     444        memProblemCallback(ptr, __func__, __LINE__);
     445    }
     446
     447    ptr->refCounter--;
     448
     449    return vptr;
     450}
Note: See TracChangeset for help on using the changeset viewer.