Changeset 472
- Timestamp:
- Apr 19, 2004, 5:08:35 PM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 2 edited
-
sys/psMemory.c (modified) (13 diffs)
-
sysUtils/psMemory.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMemory.c
r471 r472 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.1 3$ $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 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 static void *memExhaustedCallbackDefault(size_t size) 40 40 { 41 return NULL;41 return NULL; 42 42 } 43 43 … … 46 46 psMemExhaustedCallback psMemExhaustedSetCallback(psMemExhaustedCallback func) 47 47 { 48 psMemExhaustedCallback old = memExhaustedCallback;49 50 if (func != NULL)51 { 52 memExhaustedCallback = func;53 } 54 else55 { 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; 60 60 } 61 61 … … 63 63 const char *file, int lineno) 64 64 { 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); 83 83 } 84 84 } … … 87 87 psMemProblemCallback psMemProblemSetCallback(psMemProblemCallback func) 88 88 { 89 psMemProblemCallback old = memProblemCallback;90 91 if (func != NULL)92 { 93 memProblemCallback = func;94 } 95 else96 { 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; 101 101 } 102 102 /* … … 110 110 long psMemSetAllocateID(long id) // set p_psMemAllocateID to id 111 111 { 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; 116 116 } 117 117 118 118 long psMemSetFreeID(long id) // set p_psMemFreeID to id 119 119 { 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; 124 124 } 125 125 … … 132 132 static long memAllocateCallbackDefault(const psMemBlock *ptr) 133 133 { 134 static int incr = 0; // "p_psMemAllocateID += incr"135 136 return incr;134 static int incr = 0; // "p_psMemAllocateID += incr" 135 136 return incr; 137 137 } 138 138 139 139 static long memFreeCallbackDefault(const psMemBlock *ptr) 140 140 { 141 static int incr = 0; // "p_psMemFreeID += incr"142 143 return incr;141 static int incr = 0; // "p_psMemFreeID += incr" 142 143 return incr; 144 144 } 145 145 … … 152 152 psMemAllocateCallback psMemAllocateSetCallback(psMemAllocateCallback func) 153 153 { 154 psMemFreeCallback old = memAllocateCallback;155 156 if (func != NULL)157 { 158 memAllocateCallback = func;159 } 160 else161 { 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; 166 166 } 167 167 168 168 psMemFreeCallback psMemFreeSetCallback(psMemFreeCallback func) 169 169 { 170 psMemFreeCallback old = memFreeCallback;171 172 if (func != NULL)173 { 174 memFreeCallback = func;175 } 176 else177 { 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; 182 182 } 183 183 … … 187 187 int psMemGetId(void) 188 188 { 189 return memid + 1;189 return memid + 1; 190 190 } 191 191 … … 201 201 const char* funcName) 202 202 { 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); 225 225 } 226 226 227 227 int psMemCheckCorruption(int abort_on_error) 228 228 { 229 int nbad = 0; // number of bad blocks230 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) 243 243 { 244 // release the lock on the memblock list245 pthread_mutex_unlock(&memBlockListMutex);246 psAbort(__func__, "Detected memory corruption");247 return nbad;248 } 249 } 250 } 251 252 // release the lock on the memblock list253 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; 255 255 } 256 256 257 257 void *p_psAlloc(size_t size, const char *file, int lineno) 258 258 { 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 far277 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-list282 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 allocated299 return ptr + 1; // user memory259 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 300 300 } 301 301 302 302 void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno) 303 303 { 304 if (vptr == NULL)305 { 306 return p_psAlloc(size, file, lineno);307 } 308 else309 { 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 memory304 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 329 329 } 330 330 } … … 332 332 void p_psFree(void *vptr, const char *file, int lineno) 333 333 { 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 it350 } 351 else352 { 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 else361 { 362 363 // cut the memBlock out of the memBlock list364 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) 366 366 { 367 ptr->nextBlock->previousBlock = ptr->previousBlock;368 } 369 if (ptr->previousBlock != NULL)367 ptr->nextBlock->previousBlock = ptr->previousBlock; 368 } 369 if (ptr->previousBlock != NULL) 370 370 { 371 ptr->previousBlock->nextBlock = ptr->nextBlock;372 } 373 if (lastMemBlockAllocated == ptr)371 ptr->previousBlock->nextBlock = ptr->nextBlock; 372 } 373 if (lastMemBlockAllocated == ptr) 374 374 { 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); 381 381 } 382 382 } … … 387 387 */ 388 388 int psMemCheckLeaks( 389 int id0, // don't list blocks with id < id0390 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL391 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) 405 405 { 406 if (nleak == 1)406 if (nleak == 1) 407 407 { 408 fprintf(fd, " %20s:line ID\n", "file");408 fprintf(fd, " %20s:line ID\n", "file"); 409 409 } 410 410 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) 435 435 { // 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; 444 444 } 445 445 … … 449 449 int psMemGetRefCounter(void *vptr) // return refCounter 450 450 { 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; 459 459 } 460 460 461 461 void *psMemIncrRefCounter(void *vptr) // increment and return refCounter 462 462 { 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; 478 478 } 479 479 480 480 void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter 481 481 { 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 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-04-20 03:0 7:53$10 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-04-20 03:08:16 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 static void *memExhaustedCallbackDefault(size_t size) 40 40 { 41 return NULL;41 return NULL; 42 42 } 43 43 … … 46 46 psMemExhaustedCallback psMemExhaustedSetCallback(psMemExhaustedCallback func) 47 47 { 48 psMemExhaustedCallback old = memExhaustedCallback;49 50 if (func != NULL)51 { 52 memExhaustedCallback = func;53 } 54 else55 { 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; 60 60 } 61 61 … … 63 63 const char *file, int lineno) 64 64 { 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); 83 83 } 84 84 } … … 87 87 psMemProblemCallback psMemProblemSetCallback(psMemProblemCallback func) 88 88 { 89 psMemProblemCallback old = memProblemCallback;90 91 if (func != NULL)92 { 93 memProblemCallback = func;94 } 95 else96 { 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; 101 101 } 102 102 /* … … 110 110 long psMemSetAllocateID(long id) // set p_psMemAllocateID to id 111 111 { 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; 116 116 } 117 117 118 118 long psMemSetFreeID(long id) // set p_psMemFreeID to id 119 119 { 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; 124 124 } 125 125 … … 132 132 static long memAllocateCallbackDefault(const psMemBlock *ptr) 133 133 { 134 static int incr = 0; // "p_psMemAllocateID += incr"135 136 return incr;134 static int incr = 0; // "p_psMemAllocateID += incr" 135 136 return incr; 137 137 } 138 138 139 139 static long memFreeCallbackDefault(const psMemBlock *ptr) 140 140 { 141 static int incr = 0; // "p_psMemFreeID += incr"142 143 return incr;141 static int incr = 0; // "p_psMemFreeID += incr" 142 143 return incr; 144 144 } 145 145 … … 152 152 psMemAllocateCallback psMemAllocateSetCallback(psMemAllocateCallback func) 153 153 { 154 psMemFreeCallback old = memAllocateCallback;155 156 if (func != NULL)157 { 158 memAllocateCallback = func;159 } 160 else161 { 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; 166 166 } 167 167 168 168 psMemFreeCallback psMemFreeSetCallback(psMemFreeCallback func) 169 169 { 170 psMemFreeCallback old = memFreeCallback;171 172 if (func != NULL)173 { 174 memFreeCallback = func;175 } 176 else177 { 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; 182 182 } 183 183 … … 187 187 int psMemGetId(void) 188 188 { 189 return memid + 1;189 return memid + 1; 190 190 } 191 191 … … 201 201 const char* funcName) 202 202 { 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); 225 225 } 226 226 227 227 int psMemCheckCorruption(int abort_on_error) 228 228 { 229 int nbad = 0; // number of bad blocks230 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) 243 243 { 244 // release the lock on the memblock list245 pthread_mutex_unlock(&memBlockListMutex);246 psAbort(__func__, "Detected memory corruption");247 return nbad;248 } 249 } 250 } 251 252 // release the lock on the memblock list253 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; 255 255 } 256 256 257 257 void *p_psAlloc(size_t size, const char *file, int lineno) 258 258 { 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 far277 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-list282 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 allocated299 return ptr + 1; // user memory259 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 300 300 } 301 301 302 302 void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno) 303 303 { 304 if (vptr == NULL)305 { 306 return p_psAlloc(size, file, lineno);307 } 308 else309 { 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 memory304 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 329 329 } 330 330 } … … 332 332 void p_psFree(void *vptr, const char *file, int lineno) 333 333 { 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 it350 } 351 else352 { 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 else361 { 362 363 // cut the memBlock out of the memBlock list364 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) 366 366 { 367 ptr->nextBlock->previousBlock = ptr->previousBlock;368 } 369 if (ptr->previousBlock != NULL)367 ptr->nextBlock->previousBlock = ptr->previousBlock; 368 } 369 if (ptr->previousBlock != NULL) 370 370 { 371 ptr->previousBlock->nextBlock = ptr->nextBlock;372 } 373 if (lastMemBlockAllocated == ptr)371 ptr->previousBlock->nextBlock = ptr->nextBlock; 372 } 373 if (lastMemBlockAllocated == ptr) 374 374 { 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); 381 381 } 382 382 } … … 387 387 */ 388 388 int psMemCheckLeaks( 389 int id0, // don't list blocks with id < id0390 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL391 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) 405 405 { 406 if (nleak == 1)406 if (nleak == 1) 407 407 { 408 fprintf(fd, " %20s:line ID\n", "file");408 fprintf(fd, " %20s:line ID\n", "file"); 409 409 } 410 410 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) 435 435 { // 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; 444 444 } 445 445 … … 449 449 int psMemGetRefCounter(void *vptr) // return refCounter 450 450 { 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; 459 459 } 460 460 461 461 void *psMemIncrRefCounter(void *vptr) // increment and return refCounter 462 462 { 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; 478 478 } 479 479 480 480 void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter 481 481 { 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.
