IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 472


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

* empty log message *

Location:
trunk/psLib/src
Files:
2 edited

Legend:

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

    r471 r472  
    88 *  @author Robert Lupton, Princeton University
    99 *
    10  *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-04-20 03:08:16 $
     10 *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2004-04-20 03:08:35 $
    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    {
     52      memExhaustedCallback = func;
     53    }
     54  else
     55    {
     56      memExhaustedCallback = memExhaustedCallbackDefault;
     57    }
     58
     59  return old;
    6060}
    6161
     
    6363                                      const char *file, int lineno)
    6464{
    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);
     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);
    8383    }
    8484}
     
    8787psMemProblemCallback psMemProblemSetCallback(psMemProblemCallback func)
    8888{
    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;
     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;
    101101}
    102102/*
     
    110110long psMemSetAllocateID(long id) // set p_psMemAllocateID to id
    111111{
    112     long old = p_psMemAllocateID;
    113     p_psMemAllocateID = id;
    114 
    115     return old;
     112  long old = p_psMemAllocateID;
     113  p_psMemAllocateID = id;
     114
     115  return old;
    116116}
    117117
    118118long psMemSetFreeID(long id)  // set p_psMemFreeID to id
    119119{
    120     long old = p_psMemFreeID;
    121     p_psMemFreeID = id;
    122 
    123     return old;
     120  long old = p_psMemFreeID;
     121  p_psMemFreeID = id;
     122
     123  return old;
    124124}
    125125
     
    132132static long memAllocateCallbackDefault(const psMemBlock *ptr)
    133133{
    134     static int incr = 0;  // "p_psMemAllocateID += incr"
    135 
    136     return incr;
     134  static int incr = 0;  // "p_psMemAllocateID += incr"
     135
     136  return incr;
    137137}
    138138
    139139static long memFreeCallbackDefault(const psMemBlock *ptr)
    140140{
    141     static int incr = 0;  // "p_psMemFreeID += incr"
    142 
    143     return incr;
     141  static int incr = 0;  // "p_psMemFreeID += incr"
     142
     143  return incr;
    144144}
    145145
     
    152152psMemAllocateCallback psMemAllocateSetCallback(psMemAllocateCallback func)
    153153{
    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;
     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;
    166166}
    167167
    168168psMemFreeCallback psMemFreeSetCallback(psMemFreeCallback func)
    169169{
    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;
     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;
    182182}
    183183
     
    187187int psMemGetId(void)
    188188{
    189     return memid + 1;
     189  return memid + 1;
    190190}
    191191
     
    201201              const char* funcName)
    202202{
    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);
     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);
    225225}
    226226
    227227int psMemCheckCorruption(int abort_on_error)
    228228{
    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)
     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)
    243243            {
    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;
     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;
    255255}
    256256
    257257void *p_psAlloc(size_t size, const char *file, int lineno)
    258258{
    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
     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
    300300}
    301301
    302302void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
    303303{
    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
     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
    329329    }
    330330}
     
    332332void p_psFree(void *vptr, const char *file, int lineno)
    333333{
    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)
     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)
    366366            {
    367                 ptr->nextBlock->previousBlock = ptr->previousBlock;
    368             }
    369             if (ptr->previousBlock != NULL)
     367              ptr->nextBlock->previousBlock = ptr->previousBlock;
     368            }
     369          if (ptr->previousBlock != NULL)
    370370            {
    371                 ptr->previousBlock->nextBlock = ptr->nextBlock;
    372             }
    373             if (lastMemBlockAllocated == ptr)
     371              ptr->previousBlock->nextBlock = ptr->nextBlock;
     372            }
     373          if (lastMemBlockAllocated == ptr)
    374374            {
    375                 lastMemBlockAllocated = ptr->nextBlock;
    376             }
    377 
    378             pthread_mutex_unlock(&memBlockListMutex);
    379 
    380             free(ptr);
     375              lastMemBlockAllocated = ptr->nextBlock;
     376            }
     377
     378          pthread_mutex_unlock(&memBlockListMutex);
     379
     380          free(ptr);
    381381        }
    382382    }
     
    387387 */
    388388int 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)
     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)
    405405            {
    406                 if (nleak == 1)
     406              if (nleak == 1)
    407407                {
    408                     fprintf(fd, "   %20s:line ID\n", "file");
     408                  fprintf(fd, "   %20s:line ID\n", "file");
    409409                }
    410410
    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)
     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)
    435435            { // found them all
    436                 break;
    437             }
    438         }
    439     }
    440 
    441     pthread_mutex_unlock(&memBlockListMutex);
    442 
    443     return nleak;
     436              break;
     437            }
     438        }
     439    }
     440
     441  pthread_mutex_unlock(&memBlockListMutex);
     442
     443  return nleak;
    444444}
    445445
     
    449449int psMemGetRefCounter(void *vptr) // return refCounter
    450450{
    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;
     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;
    459459}
    460460
    461461void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
    462462{
    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;
     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;
    478478}
    479479
    480480void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
    481481{
    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 }
     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}
  • trunk/psLib/src/sysUtils/psMemory.c

    r471 r472  
    88 *  @author Robert Lupton, Princeton University
    99 *
    10  *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2004-04-20 03:07:53 $
     10 *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2004-04-20 03:08:16 $
    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    {
     52        memExhaustedCallback = func;
     53    }
     54    else
     55    {
     56        memExhaustedCallback = memExhaustedCallbackDefault;
     57    }
     58
     59    return old;
    6060}
    6161
     
    6363                                      const char *file, int lineno)
    6464{
    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);
     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);
    8383    }
    8484}
     
    8787psMemProblemCallback psMemProblemSetCallback(psMemProblemCallback func)
    8888{
    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;
     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;
    101101}
    102102/*
     
    110110long psMemSetAllocateID(long id) // set p_psMemAllocateID to id
    111111{
    112   long old = p_psMemAllocateID;
    113   p_psMemAllocateID = id;
    114 
    115   return old;
     112    long old = p_psMemAllocateID;
     113    p_psMemAllocateID = id;
     114
     115    return old;
    116116}
    117117
    118118long psMemSetFreeID(long id)  // set p_psMemFreeID to id
    119119{
    120   long old = p_psMemFreeID;
    121   p_psMemFreeID = id;
    122 
    123   return old;
     120    long old = p_psMemFreeID;
     121    p_psMemFreeID = id;
     122
     123    return old;
    124124}
    125125
     
    132132static long memAllocateCallbackDefault(const psMemBlock *ptr)
    133133{
    134   static int incr = 0;  // "p_psMemAllocateID += incr"
    135 
    136   return incr;
     134    static int incr = 0;  // "p_psMemAllocateID += incr"
     135
     136    return incr;
    137137}
    138138
    139139static long memFreeCallbackDefault(const psMemBlock *ptr)
    140140{
    141   static int incr = 0;  // "p_psMemFreeID += incr"
    142 
    143   return incr;
     141    static int incr = 0;  // "p_psMemFreeID += incr"
     142
     143    return incr;
    144144}
    145145
     
    152152psMemAllocateCallback psMemAllocateSetCallback(psMemAllocateCallback func)
    153153{
    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;
     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;
    166166}
    167167
    168168psMemFreeCallback psMemFreeSetCallback(psMemFreeCallback func)
    169169{
    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;
     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;
    182182}
    183183
     
    187187int psMemGetId(void)
    188188{
    189   return memid + 1;
     189    return memid + 1;
    190190}
    191191
     
    201201              const char* funcName)
    202202{
    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);
     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);
    225225}
    226226
    227227int psMemCheckCorruption(int abort_on_error)
    228228{
    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)
     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)
    243243            {
    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;
     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;
    255255}
    256256
    257257void *p_psAlloc(size_t size, const char *file, int lineno)
    258258{
    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
     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
    300300}
    301301
    302302void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
    303303{
    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
     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
    329329    }
    330330}
     
    332332void p_psFree(void *vptr, const char *file, int lineno)
    333333{
    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)
     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)
    366366            {
    367               ptr->nextBlock->previousBlock = ptr->previousBlock;
    368             }
    369           if (ptr->previousBlock != NULL)
     367                ptr->nextBlock->previousBlock = ptr->previousBlock;
     368            }
     369            if (ptr->previousBlock != NULL)
    370370            {
    371               ptr->previousBlock->nextBlock = ptr->nextBlock;
    372             }
    373           if (lastMemBlockAllocated == ptr)
     371                ptr->previousBlock->nextBlock = ptr->nextBlock;
     372            }
     373            if (lastMemBlockAllocated == ptr)
    374374            {
    375               lastMemBlockAllocated = ptr->nextBlock;
    376             }
    377 
    378           pthread_mutex_unlock(&memBlockListMutex);
    379 
    380           free(ptr);
     375                lastMemBlockAllocated = ptr->nextBlock;
     376            }
     377
     378            pthread_mutex_unlock(&memBlockListMutex);
     379
     380            free(ptr);
    381381        }
    382382    }
     
    387387 */
    388388int 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)
     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)
    405405            {
    406               if (nleak == 1)
     406                if (nleak == 1)
    407407                {
    408                   fprintf(fd, "   %20s:line ID\n", "file");
     408                    fprintf(fd, "   %20s:line ID\n", "file");
    409409                }
    410410
    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)
     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)
    435435            { // found them all
    436               break;
    437             }
    438         }
    439     }
    440 
    441   pthread_mutex_unlock(&memBlockListMutex);
    442 
    443   return nleak;
     436                break;
     437            }
     438        }
     439    }
     440
     441    pthread_mutex_unlock(&memBlockListMutex);
     442
     443    return nleak;
    444444}
    445445
     
    449449int psMemGetRefCounter(void *vptr) // return refCounter
    450450{
    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;
     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;
    459459}
    460460
    461461void *psMemIncrRefCounter(void *vptr) // increment and return refCounter
    462462{
    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;
     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;
    478478}
    479479
    480480void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter
    481481{
    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 }
     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}
Note: See TracChangeset for help on using the changeset viewer.