Changeset 451
- Timestamp:
- Apr 19, 2004, 10:14:04 AM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 4 edited
-
sys/psMemory.c (modified) (13 diffs)
-
sys/psMemory.h (modified) (3 diffs)
-
sysUtils/psMemory.c (modified) (13 diffs)
-
sysUtils/psMemory.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMemory.c
r432 r451 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1. 2$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-04-1 6 02:18:57$10 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-04-19 20:14:04 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 16 16 #define PS_ALLOW_MALLOC // we're allowed to call malloc() 17 17 18 #include <pthread.h> // we need a mutex to make this stuff thread safe. 18 19 #include <stdlib.h> 19 20 #include <stdio.h> … … 25 26 26 27 static int checkMemBlock(const psMemBlock *m, const char* funcName); 27 static int numMemBlock = 0; // size of memBlocks28 static psMemBlock **memBlocks = NULL;28 static psMemBlock *lastMemBlockAllocated = NULL; 29 pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER; 29 30 30 31 /** … … 183 184 184 185 static int 185 checkMemBlock(const psMemBlock *m, // block to check 186 const char* funcName) // be quiet? 187 { 186 checkMemBlock(const psMemBlock *m, 187 const char* funcName) 188 { 189 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 190 // we shouldn't call such things as p_psAlloc/p_psFree here. 191 188 192 if (m == NULL) { 189 193 psError(funcName,"Memory Corruption: NULL memory block found."); … … 206 210 int psMemCheckCorruption(int abort_on_error) 207 211 { 208 int nbad = 0; // number of bad blocks 209 210 if (memBlocks == NULL) { 211 return 0; // no memory is allocated to be corrupted 212 } 213 214 for (int i = 1; i <= memid; i++) { 215 if (memBlocks[i] != NULL) { 216 if (checkMemBlock(memBlocks[i], __func__)) { 217 nbad++; 218 219 memProblemCallback(memBlocks[i], __func__, __LINE__); 220 221 if (abort_on_error) { 222 psAbort(__func__, "Detected memory corruption"); 223 } 224 } 212 int nbad = 0; // number of bad blocks 213 214 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 215 pthread_mutex_lock(&memBlockListMutex); 216 217 for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) 218 { 219 if (checkMemBlock(iter, __func__)) { 220 nbad++; 221 222 memProblemCallback(iter, __func__, __LINE__); 223 224 if (abort_on_error) { 225 // release the lock on the memblock list 226 pthread_mutex_unlock(&memBlockListMutex); 227 psAbort(__func__, "Detected memory corruption"); 228 return nbad; 229 } 225 230 } 226 231 } 227 232 233 // release the lock on the memblock list 234 pthread_mutex_unlock(&memBlockListMutex); 228 235 return nbad; 229 236 } … … 243 250 } 244 251 245 *(unsigned long *)&ptr->id = ++memid;252 *(unsigned long*)&ptr->id = ++memid; 246 253 ptr->file = file; 247 *( int*)&ptr->lineno = lineno;254 *(unsigned int*)&ptr->lineno = lineno; 248 255 ptr->startblock = P_PS_MEMMAGIC; 249 256 ptr->endblock = P_PS_MEMMAGIC; 250 251 ptr->refCounter = 1; // one user so far 252 /* 253 * Did the user ask to be informed about this allocation? 254 */ 255 256 if (ptr->id == p_psMemAllocateID && p_psMemAllocateID > 0) { 257 ptr->refCounter = 1; // one user so far 258 259 // need exclusive access of the memory block list now... 260 pthread_mutex_lock(&memBlockListMutex); 261 262 // insert the new block to the front of the memBlock linked-list 263 ptr->previousBlock = NULL; 264 ptr->nextBlock = lastMemBlockAllocated; 265 if (ptr->nextBlock != NULL) { 266 ptr->nextBlock->previousBlock = ptr; 267 } 268 lastMemBlockAllocated = ptr; 269 270 pthread_mutex_unlock(&memBlockListMutex); 271 272 // Did the user ask to be informed about this allocation? 273 if (ptr->id == p_psMemAllocateID) { 257 274 p_psMemAllocateID += memAllocateCallback(ptr); 258 275 } 259 if (memid >= numMemBlock) { 260 numMemBlock = (numMemBlock == 0) ? 100000 : 2*numMemBlock; 261 memBlocks = realloc(memBlocks, numMemBlock*sizeof(psMemBlock *)); // NOT psRealloc 262 } 263 memBlocks[ptr->id] = ptr; 264 /* 265 * And return the user the memory that they allocated 266 */ 267 return ptr + 1; // usr memory 276 277 // And return the user the memory that they allocated 278 return ptr + 1; // user memory 268 279 } 269 280 … … 274 285 } else { 275 286 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 276 ptr = (psMemBlock *)realloc(ptr, sizeof(psMemBlock) + size); 277 memBlocks[ptr->id] = ptr; 278 279 return ptr + 1; // usr memory 287 288 pthread_mutex_lock(&memBlockListMutex); 289 290 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size); 291 292 // the block location may have changed, so fix the linked list addresses. 293 if (ptr->nextBlock != NULL) { 294 ptr->nextBlock->previousBlock = ptr; 295 } 296 if (ptr->previousBlock != NULL) { 297 ptr->previousBlock->nextBlock = ptr; 298 } 299 300 pthread_mutex_unlock(&memBlockListMutex); 301 302 return ptr + 1; // usr memory 280 303 } 281 304 } … … 288 311 289 312 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 290 /* 291 * Did the user ask to be informed about this deallocation? 292 */ 293 if (ptr->id == p_psMemFreeID && p_psMemFreeID > 0) { 313 314 // Did the user ask to be informed about this deallocation? 315 if (ptr->id == p_psMemFreeID) { 294 316 p_psMemFreeID += memFreeCallback(ptr); 295 317 } … … 298 320 memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it 299 321 } else { 300 if (ptr->refCounter != 1) { 322 if (ptr->refCounter > 1) { 323 psError(__func__,"The buffer being freed is referenced elsewhere. " 324 "Buffer's reference count was decremented instead."); 325 ptr->refCounter--; 301 326 memProblemCallback(ptr, file, lineno); 327 } else { 328 329 // cut the memBlock out of the memBlock list 330 pthread_mutex_lock(&memBlockListMutex); 331 if (ptr->nextBlock != NULL) { 332 ptr->nextBlock->previousBlock = ptr->previousBlock; 333 } 334 if (ptr->previousBlock != NULL) { 335 ptr->previousBlock->nextBlock = ptr->nextBlock; 336 } 337 if (lastMemBlockAllocated == ptr) { 338 lastMemBlockAllocated = ptr->nextBlock; 339 } 340 341 pthread_mutex_unlock(&memBlockListMutex); 342 343 free(ptr); 344 } 345 } 346 } 347 348 /*****************************************************************************/ 349 /* 350 * Check for memory leaks. Not production quality code 351 */ 352 int psMemCheckLeaks( 353 int id0, // don't list blocks with id < id0 354 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL 355 FILE *fd) // print list of leaks to fd (or NULL) 356 { 357 int nleak = 0; 358 int j = 0; 359 360 pthread_mutex_lock(&memBlockListMutex); 361 362 for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) { 363 if ( (iter->refCounter > 0) && (iter->id >= id0) ) { 364 nleak++; 365 366 if (fd != NULL) { 367 if (nleak == 1) { 368 fprintf(fd, " %20s:line ID\n", "file"); 369 } 370 371 fprintf(fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id); 372 } 373 } 374 } 375 376 pthread_mutex_unlock(&memBlockListMutex); 377 378 if (nleak == 0 || arr == NULL) { 379 return nleak; 380 } 381 382 p_psFree(*arr,__FILE__, __LINE__); // Don't generate a memory leak! 383 384 *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__); 385 386 pthread_mutex_lock(&memBlockListMutex); 387 388 for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) { 389 if ( (iter->refCounter > 0) && (iter->id >= id0) ) { 390 (*arr)[j++] = iter; 391 if (j == nleak) { // found them all 392 break; 393 } 302 394 } 303 ptr->refCounter--; 304 #if 1 305 306 memBlocks[ptr->id] = NULL; // XXX sub-optimal! Can't check 307 // freed blocks for corruption/double frees 308 free(ptr); 309 #endif 310 311 } 312 } 313 314 /*****************************************************************************/ 315 /* 316 * Check for memory leaks. Not production quality code 317 */ 318 int psMemCheckLeaks( 319 int id0, // don't list blocks with id < id0 320 psMemBlock ***arr, // pointer to array of pointers to 321 // leaked blocks, or NULL 322 FILE *fd) // print list of leaks to fd (or NULL) 323 { 324 int nleak = 0; 325 326 if (memBlocks == NULL) 327 { // nothing was allocated 328 return 0; 329 } 330 331 for (int i = id0; i <= memid; i++) 332 { 333 if (memBlocks[i] != NULL) { 334 if (memBlocks[i]->refCounter > 0) { 335 nleak++; 336 337 if (fd != NULL) { 338 if (nleak == 1) { 339 fprintf(fd, " %20s:line ID\n", "file"); 340 } 341 342 fprintf(fd, " %20s:%-4d %ld\n", 343 memBlocks[i]->file, memBlocks[i]->lineno, 344 memBlocks[i]->id); 345 } 346 } 347 } 348 } 349 350 if (nleak == 0 || arr == NULL) 351 { 352 return nleak; 353 } 354 355 p_psFree(*arr,__FILE__, __LINE__); // Don't generate a memory leak! 356 357 *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__); 358 for (int i = id0, j = 0; i < memid; i++) 359 { 360 if (memBlocks[i] != NULL) { 361 if (memBlocks[i]->refCounter > 0) { 362 (*arr)[j++] = memBlocks[i]; 363 if (j == nleak) { // found them all 364 break; 365 } 366 } 367 } 368 } 395 } 396 397 pthread_mutex_unlock(&memBlockListMutex); 369 398 370 399 return nleak; … … 389 418 void *psMemIncrRefCounter(void *vptr) // increment and return refCounter 390 419 { 391 if (vptr == NULL) 392 { 420 if (vptr == NULL) { 393 421 return vptr; 394 422 } … … 396 424 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 397 425 398 if (checkMemBlock(ptr, __func__)) 399 { 426 if (checkMemBlock(ptr, __func__)) { 400 427 memProblemCallback(ptr, __func__, __LINE__); 401 428 } … … 408 435 void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter 409 436 { 410 if (vptr == NULL) 411 { 437 if (vptr == NULL) { 412 438 return vptr; 413 439 } … … 415 441 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 416 442 417 if (checkMemBlock(ptr, __func__)) 418 { 443 if (checkMemBlock(ptr, __func__)) { 419 444 memProblemCallback(ptr, __func__, __LINE__); 420 445 } -
trunk/psLib/src/sys/psMemory.h
r432 r451 14 14 * @author Robert Lupton, Princeton University 15 15 * 16 * @version $Revision: 1. 2$ $Name: not supported by cvs2svn $17 * @date $Date: 2004-04-1 6 02:18:57$16 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 17 * @date $Date: 2004-04-19 20:14:04 $ 18 18 * 19 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 25 25 * aligned for all storage types. 26 26 */ 27 typedef struct 27 typedef struct psMemBlock 28 28 { 29 const void *startblock; ///< initialised to p_psMEMMAGIC 29 const void* startblock; ///< initialised to p_psMEMMAGIC 30 struct psMemBlock* previousBlock; ///< previous block in allocation list 31 struct psMemBlock* nextBlock; ///< next block allocation list 30 32 const unsigned long id; ///< a unique ID for this allocation 31 const char *file; ///< set from __FILE__ in e.g. p_psAlloc33 const char* file; ///< set from __FILE__ in e.g. p_psAlloc 32 34 const int lineno; ///< set from __LINE__ in e.g. p_psAlloc 33 int refCounter; ///< how many times pointer is referenced 34 const void **endpost; ///< initialised to p_psMEMMAGIC 35 const void *endblock; ///< initialised to p_psMEMMAGIC 35 unsigned int refCounter; ///< how many times pointer is referenced 36 const void* endblock; ///< initialised to p_psMEMMAGIC 36 37 } 37 38 psMemBlock; … … 43 44 typedef long (*psMemFreeCallback)(const psMemBlock *ptr); 44 45 45 /// prototype of a callback used in error conditions 46 /** prototype of a callback used in error conditions 47 * 48 * This callback should never try to call psAlloc or psFree. 49 * 50 */ 46 51 typedef void (*psMemProblemCallback)(const psMemBlock *ptr, const char *file, int lineno); 47 52 -
trunk/psLib/src/sysUtils/psMemory.c
r432 r451 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1. 2$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-04-1 6 02:18:57$10 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-04-19 20:14:04 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 16 16 #define PS_ALLOW_MALLOC // we're allowed to call malloc() 17 17 18 #include <pthread.h> // we need a mutex to make this stuff thread safe. 18 19 #include <stdlib.h> 19 20 #include <stdio.h> … … 25 26 26 27 static int checkMemBlock(const psMemBlock *m, const char* funcName); 27 static int numMemBlock = 0; // size of memBlocks28 static psMemBlock **memBlocks = NULL;28 static psMemBlock *lastMemBlockAllocated = NULL; 29 pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER; 29 30 30 31 /** … … 183 184 184 185 static int 185 checkMemBlock(const psMemBlock *m, // block to check 186 const char* funcName) // be quiet? 187 { 186 checkMemBlock(const psMemBlock *m, 187 const char* funcName) 188 { 189 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 190 // we shouldn't call such things as p_psAlloc/p_psFree here. 191 188 192 if (m == NULL) { 189 193 psError(funcName,"Memory Corruption: NULL memory block found."); … … 206 210 int psMemCheckCorruption(int abort_on_error) 207 211 { 208 int nbad = 0; // number of bad blocks 209 210 if (memBlocks == NULL) { 211 return 0; // no memory is allocated to be corrupted 212 } 213 214 for (int i = 1; i <= memid; i++) { 215 if (memBlocks[i] != NULL) { 216 if (checkMemBlock(memBlocks[i], __func__)) { 217 nbad++; 218 219 memProblemCallback(memBlocks[i], __func__, __LINE__); 220 221 if (abort_on_error) { 222 psAbort(__func__, "Detected memory corruption"); 223 } 224 } 212 int nbad = 0; // number of bad blocks 213 214 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 215 pthread_mutex_lock(&memBlockListMutex); 216 217 for (psMemBlock* iter=lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) 218 { 219 if (checkMemBlock(iter, __func__)) { 220 nbad++; 221 222 memProblemCallback(iter, __func__, __LINE__); 223 224 if (abort_on_error) { 225 // release the lock on the memblock list 226 pthread_mutex_unlock(&memBlockListMutex); 227 psAbort(__func__, "Detected memory corruption"); 228 return nbad; 229 } 225 230 } 226 231 } 227 232 233 // release the lock on the memblock list 234 pthread_mutex_unlock(&memBlockListMutex); 228 235 return nbad; 229 236 } … … 243 250 } 244 251 245 *(unsigned long *)&ptr->id = ++memid;252 *(unsigned long*)&ptr->id = ++memid; 246 253 ptr->file = file; 247 *( int*)&ptr->lineno = lineno;254 *(unsigned int*)&ptr->lineno = lineno; 248 255 ptr->startblock = P_PS_MEMMAGIC; 249 256 ptr->endblock = P_PS_MEMMAGIC; 250 251 ptr->refCounter = 1; // one user so far 252 /* 253 * Did the user ask to be informed about this allocation? 254 */ 255 256 if (ptr->id == p_psMemAllocateID && p_psMemAllocateID > 0) { 257 ptr->refCounter = 1; // one user so far 258 259 // need exclusive access of the memory block list now... 260 pthread_mutex_lock(&memBlockListMutex); 261 262 // insert the new block to the front of the memBlock linked-list 263 ptr->previousBlock = NULL; 264 ptr->nextBlock = lastMemBlockAllocated; 265 if (ptr->nextBlock != NULL) { 266 ptr->nextBlock->previousBlock = ptr; 267 } 268 lastMemBlockAllocated = ptr; 269 270 pthread_mutex_unlock(&memBlockListMutex); 271 272 // Did the user ask to be informed about this allocation? 273 if (ptr->id == p_psMemAllocateID) { 257 274 p_psMemAllocateID += memAllocateCallback(ptr); 258 275 } 259 if (memid >= numMemBlock) { 260 numMemBlock = (numMemBlock == 0) ? 100000 : 2*numMemBlock; 261 memBlocks = realloc(memBlocks, numMemBlock*sizeof(psMemBlock *)); // NOT psRealloc 262 } 263 memBlocks[ptr->id] = ptr; 264 /* 265 * And return the user the memory that they allocated 266 */ 267 return ptr + 1; // usr memory 276 277 // And return the user the memory that they allocated 278 return ptr + 1; // user memory 268 279 } 269 280 … … 274 285 } else { 275 286 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 276 ptr = (psMemBlock *)realloc(ptr, sizeof(psMemBlock) + size); 277 memBlocks[ptr->id] = ptr; 278 279 return ptr + 1; // usr memory 287 288 pthread_mutex_lock(&memBlockListMutex); 289 290 ptr = (psMemBlock*)realloc(ptr, sizeof(psMemBlock) + size); 291 292 // the block location may have changed, so fix the linked list addresses. 293 if (ptr->nextBlock != NULL) { 294 ptr->nextBlock->previousBlock = ptr; 295 } 296 if (ptr->previousBlock != NULL) { 297 ptr->previousBlock->nextBlock = ptr; 298 } 299 300 pthread_mutex_unlock(&memBlockListMutex); 301 302 return ptr + 1; // usr memory 280 303 } 281 304 } … … 288 311 289 312 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 290 /* 291 * Did the user ask to be informed about this deallocation? 292 */ 293 if (ptr->id == p_psMemFreeID && p_psMemFreeID > 0) { 313 314 // Did the user ask to be informed about this deallocation? 315 if (ptr->id == p_psMemFreeID) { 294 316 p_psMemFreeID += memFreeCallback(ptr); 295 317 } … … 298 320 memProblemCallback(ptr, file, lineno); // we may not own this block; don't free it 299 321 } else { 300 if (ptr->refCounter != 1) { 322 if (ptr->refCounter > 1) { 323 psError(__func__,"The buffer being freed is referenced elsewhere. " 324 "Buffer's reference count was decremented instead."); 325 ptr->refCounter--; 301 326 memProblemCallback(ptr, file, lineno); 327 } else { 328 329 // cut the memBlock out of the memBlock list 330 pthread_mutex_lock(&memBlockListMutex); 331 if (ptr->nextBlock != NULL) { 332 ptr->nextBlock->previousBlock = ptr->previousBlock; 333 } 334 if (ptr->previousBlock != NULL) { 335 ptr->previousBlock->nextBlock = ptr->nextBlock; 336 } 337 if (lastMemBlockAllocated == ptr) { 338 lastMemBlockAllocated = ptr->nextBlock; 339 } 340 341 pthread_mutex_unlock(&memBlockListMutex); 342 343 free(ptr); 344 } 345 } 346 } 347 348 /*****************************************************************************/ 349 /* 350 * Check for memory leaks. Not production quality code 351 */ 352 int psMemCheckLeaks( 353 int id0, // don't list blocks with id < id0 354 psMemBlock ***arr, // pointer to array of pointers to leaked blocks, or NULL 355 FILE *fd) // print list of leaks to fd (or NULL) 356 { 357 int nleak = 0; 358 int j = 0; 359 360 pthread_mutex_lock(&memBlockListMutex); 361 362 for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) { 363 if ( (iter->refCounter > 0) && (iter->id >= id0) ) { 364 nleak++; 365 366 if (fd != NULL) { 367 if (nleak == 1) { 368 fprintf(fd, " %20s:line ID\n", "file"); 369 } 370 371 fprintf(fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id); 372 } 373 } 374 } 375 376 pthread_mutex_unlock(&memBlockListMutex); 377 378 if (nleak == 0 || arr == NULL) { 379 return nleak; 380 } 381 382 p_psFree(*arr,__FILE__, __LINE__); // Don't generate a memory leak! 383 384 *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__); 385 386 pthread_mutex_lock(&memBlockListMutex); 387 388 for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter=iter->nextBlock) { 389 if ( (iter->refCounter > 0) && (iter->id >= id0) ) { 390 (*arr)[j++] = iter; 391 if (j == nleak) { // found them all 392 break; 393 } 302 394 } 303 ptr->refCounter--; 304 #if 1 305 306 memBlocks[ptr->id] = NULL; // XXX sub-optimal! Can't check 307 // freed blocks for corruption/double frees 308 free(ptr); 309 #endif 310 311 } 312 } 313 314 /*****************************************************************************/ 315 /* 316 * Check for memory leaks. Not production quality code 317 */ 318 int psMemCheckLeaks( 319 int id0, // don't list blocks with id < id0 320 psMemBlock ***arr, // pointer to array of pointers to 321 // leaked blocks, or NULL 322 FILE *fd) // print list of leaks to fd (or NULL) 323 { 324 int nleak = 0; 325 326 if (memBlocks == NULL) 327 { // nothing was allocated 328 return 0; 329 } 330 331 for (int i = id0; i <= memid; i++) 332 { 333 if (memBlocks[i] != NULL) { 334 if (memBlocks[i]->refCounter > 0) { 335 nleak++; 336 337 if (fd != NULL) { 338 if (nleak == 1) { 339 fprintf(fd, " %20s:line ID\n", "file"); 340 } 341 342 fprintf(fd, " %20s:%-4d %ld\n", 343 memBlocks[i]->file, memBlocks[i]->lineno, 344 memBlocks[i]->id); 345 } 346 } 347 } 348 } 349 350 if (nleak == 0 || arr == NULL) 351 { 352 return nleak; 353 } 354 355 p_psFree(*arr,__FILE__, __LINE__); // Don't generate a memory leak! 356 357 *arr = p_psAlloc(nleak*sizeof(psMemBlock), __FILE__, __LINE__); 358 for (int i = id0, j = 0; i < memid; i++) 359 { 360 if (memBlocks[i] != NULL) { 361 if (memBlocks[i]->refCounter > 0) { 362 (*arr)[j++] = memBlocks[i]; 363 if (j == nleak) { // found them all 364 break; 365 } 366 } 367 } 368 } 395 } 396 397 pthread_mutex_unlock(&memBlockListMutex); 369 398 370 399 return nleak; … … 389 418 void *psMemIncrRefCounter(void *vptr) // increment and return refCounter 390 419 { 391 if (vptr == NULL) 392 { 420 if (vptr == NULL) { 393 421 return vptr; 394 422 } … … 396 424 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 397 425 398 if (checkMemBlock(ptr, __func__)) 399 { 426 if (checkMemBlock(ptr, __func__)) { 400 427 memProblemCallback(ptr, __func__, __LINE__); 401 428 } … … 408 435 void *psMemDecrRefCounter(void *vptr) // decrement and return refCounter 409 436 { 410 if (vptr == NULL) 411 { 437 if (vptr == NULL) { 412 438 return vptr; 413 439 } … … 415 441 psMemBlock *ptr = ((psMemBlock *)vptr) - 1; 416 442 417 if (checkMemBlock(ptr, __func__)) 418 { 443 if (checkMemBlock(ptr, __func__)) { 419 444 memProblemCallback(ptr, __func__, __LINE__); 420 445 } -
trunk/psLib/src/sysUtils/psMemory.h
r432 r451 14 14 * @author Robert Lupton, Princeton University 15 15 * 16 * @version $Revision: 1. 2$ $Name: not supported by cvs2svn $17 * @date $Date: 2004-04-1 6 02:18:57$16 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 17 * @date $Date: 2004-04-19 20:14:04 $ 18 18 * 19 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 25 25 * aligned for all storage types. 26 26 */ 27 typedef struct 27 typedef struct psMemBlock 28 28 { 29 const void *startblock; ///< initialised to p_psMEMMAGIC 29 const void* startblock; ///< initialised to p_psMEMMAGIC 30 struct psMemBlock* previousBlock; ///< previous block in allocation list 31 struct psMemBlock* nextBlock; ///< next block allocation list 30 32 const unsigned long id; ///< a unique ID for this allocation 31 const char *file; ///< set from __FILE__ in e.g. p_psAlloc33 const char* file; ///< set from __FILE__ in e.g. p_psAlloc 32 34 const int lineno; ///< set from __LINE__ in e.g. p_psAlloc 33 int refCounter; ///< how many times pointer is referenced 34 const void **endpost; ///< initialised to p_psMEMMAGIC 35 const void *endblock; ///< initialised to p_psMEMMAGIC 35 unsigned int refCounter; ///< how many times pointer is referenced 36 const void* endblock; ///< initialised to p_psMEMMAGIC 36 37 } 37 38 psMemBlock; … … 43 44 typedef long (*psMemFreeCallback)(const psMemBlock *ptr); 44 45 45 /// prototype of a callback used in error conditions 46 /** prototype of a callback used in error conditions 47 * 48 * This callback should never try to call psAlloc or psFree. 49 * 50 */ 46 51 typedef void (*psMemProblemCallback)(const psMemBlock *ptr, const char *file, int lineno); 47 52
Note:
See TracChangeset
for help on using the changeset viewer.
