Changeset 1407 for trunk/psLib/src/sys/psMemory.c
- Timestamp:
- Aug 6, 2004, 2:06:06 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sys/psMemory.c (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMemory.c
r1406 r1407 1 1 2 /** @file psMemory.c 2 3 * … … 8 9 * @author Robert Lupton, Princeton University 9 10 * 10 * @version $Revision: 1.3 2$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-08-0 6 22:34:05$11 * @version $Revision: 1.33 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-07 00:06:06 $ 12 13 * 13 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 14 15 */ 15 16 16 #define PS_ALLOW_MALLOC // we're allowed to call malloc()17 #define PS_ALLOW_MALLOC // we're allowed to call malloc() 17 18 18 19 #include <stdlib.h> … … 26 27 #include "psLogMsg.h" 27 28 28 #define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header29 30 #define P_PS_LARGE_BLOCK_SIZE 65536 // size where under, we try to recycle31 32 static int checkMemBlock( const psMemBlock *m, const char* funcName);29 #define P_PS_MEMMAGIC (void *)0xdeadbeef // Magic number in psMemBlock header 30 31 #define P_PS_LARGE_BLOCK_SIZE 65536 // size where under, we try to recycle 32 33 static int checkMemBlock(const psMemBlock * m, const char *funcName); 33 34 static psMemBlock *lastMemBlockAllocated = NULL; 34 35 static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER; … … 38 39 39 40 static int recycleBins = 13; 40 static int recycleBinSize[ 14 ] =41 {42 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE43 }; 41 static int recycleBinSize[14] = { 42 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE 43 }; 44 44 45 // N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops) 45 static psMemBlock* recycleMemBlockList[ 13 ] = 46 { 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 48 }; 46 static psMemBlock *recycleMemBlockList[13] = { 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 48 }; 49 49 50 50 #ifdef PS_MEM_DEBUG 51 static psMemBlock * deadBlockList;// a place to put dead memBlocks in debug mode.51 static psMemBlock *deadBlockList; // a place to put dead memBlocks in debug mode. 52 52 #endif 53 53 54 /** 54 55 * Unique ID for allocated blocks … … 59 60 * Default memExhausted callback. 60 61 */ 61 static void *memExhaustedCallbackDefault( size_t size)62 { 63 void * ptr = NULL;64 65 pthread_mutex_lock( &recycleMemBlockListMutex);62 static void *memExhaustedCallbackDefault(size_t size) 63 { 64 void *ptr = NULL; 65 66 pthread_mutex_lock(&recycleMemBlockListMutex); 66 67 int level = recycleBins - 1; 67 while ( level >= 0 && ptr == NULL ) { 68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) { 69 psMemBlock * old = recycleMemBlockList[ level ]; 70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock; 71 free( old ); 72 ptr = malloc( size ); 68 69 while (level >= 0 && ptr == NULL) { 70 while (recycleMemBlockList[level] != NULL && ptr == NULL) { 71 psMemBlock *old = recycleMemBlockList[level]; 72 73 recycleMemBlockList[level] = recycleMemBlockList[level]->nextBlock; 74 free(old); 75 ptr = malloc(size); 73 76 } 74 77 level--; 75 78 } 76 pthread_mutex_unlock( &recycleMemBlockListMutex);79 pthread_mutex_unlock(&recycleMemBlockListMutex); 77 80 78 81 return ptr; … … 81 84 static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault; 82 85 83 psMemExhaustedCallback psMemExhaustedCallbackSet( psMemExhaustedCallback func)86 psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func) 84 87 { 85 88 psMemExhaustedCallback old = memExhaustedCallback; 86 89 87 if ( func != NULL) {90 if (func != NULL) { 88 91 memExhaustedCallback = func; 89 92 } else { … … 94 97 } 95 98 96 static void memProblemCallbackDefault( const psMemBlock *ptr, 97 const char *file, int lineno ) 98 { 99 if ( ptr->refCounter < 1 ) { 100 psError( __func__, 101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", 102 ptr->id, ptr->file, ptr->lineno, file, lineno ); 103 } 104 105 if ( lineno > 0 ) { 106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno ); 99 static void memProblemCallbackDefault(const psMemBlock * ptr, const char *file, int lineno) 100 { 101 if (ptr->refCounter < 1) { 102 psError(__func__, 103 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", 104 ptr->id, ptr->file, ptr->lineno, file, lineno); 105 } 106 107 if (lineno > 0) { 108 psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno); 107 109 } 108 110 } 109 111 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault; 110 112 111 psMemProblemCallback psMemProblemCallbackSet( psMemProblemCallback func)113 psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func) 112 114 { 113 115 psMemProblemCallback old = memProblemCallback; 114 116 115 if ( func != NULL) {117 if (func != NULL) { 116 118 memProblemCallback = func; 117 119 } else { … … 121 123 return old; 122 124 } 125 123 126 /* 124 127 * And now the I-want-to-be-informed callbacks … … 126 129 * Call the callbacks when these IDs are allocated/freed 127 130 */ 128 psMemoryId p_psMemAllocateID = 0; // notify user this block is allocated131 psMemoryId p_psMemAllocateID = 0; // notify user this block is allocated 129 132 psMemoryId p_psMemFreeID = 0; // notify user this block is freed 130 133 131 psMemoryId psMemAllocateCallbackSetID( psMemoryId id)134 psMemoryId psMemAllocateCallbackSetID(psMemoryId id) 132 135 { 133 136 psMemoryId old = p_psMemAllocateID; 137 134 138 p_psMemAllocateID = id; 135 139 … … 137 141 } 138 142 139 psMemoryId psMemFreeCallbackSetID( psMemoryId id)143 psMemoryId psMemFreeCallbackSetID(psMemoryId id) 140 144 { 141 145 psMemoryId old = p_psMemFreeID; 146 142 147 p_psMemFreeID = id; 143 148 … … 151 156 * isn't resignalled) 152 157 */ 153 static psMemoryId memAllocateCallbackDefault( const psMemBlock *ptr)154 { 155 static psMemoryId incr = 0; // "p_psMemAllocateID += incr"158 static psMemoryId memAllocateCallbackDefault(const psMemBlock * ptr) 159 { 160 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 156 161 157 162 return incr; 158 163 } 159 164 160 static psMemoryId memFreeCallbackDefault( const psMemBlock *ptr)161 { 162 static psMemoryId incr = 0; // "p_psMemFreeID += incr"165 static psMemoryId memFreeCallbackDefault(const psMemBlock * ptr) 166 { 167 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 163 168 164 169 return incr; … … 171 176 static psMemFreeCallback memFreeCallback = memFreeCallbackDefault; 172 177 173 psMemAllocateCallback psMemAllocateCallbackSet( psMemAllocateCallback func)178 psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func) 174 179 { 175 180 psMemFreeCallback old = memAllocateCallback; 176 181 177 if ( func != NULL) {182 if (func != NULL) { 178 183 memAllocateCallback = func; 179 184 } else { … … 184 189 } 185 190 186 psMemFreeCallback psMemFreeCallbackSet( psMemFreeCallback func)191 psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func) 187 192 { 188 193 psMemFreeCallback old = memFreeCallback; 189 194 190 if ( func != NULL) {195 if (func != NULL) { 191 196 memFreeCallback = func; 192 197 } else { … … 200 205 * Return memory ID counter for next block to be allocated 201 206 */ 202 psMemoryId psMemGetId( void)207 psMemoryId psMemGetId(void) 203 208 { 204 209 psMemoryId id; 205 pthread_mutex_lock( &memIdMutex ); 210 211 pthread_mutex_lock(&memIdMutex); 206 212 id = memid + 1; 207 pthread_mutex_unlock( &memIdMutex);213 pthread_mutex_unlock(&memIdMutex); 208 214 209 215 return id; … … 216 222 */ 217 223 218 static int checkMemBlock( const psMemBlock *m, const char* funcName)224 static int checkMemBlock(const psMemBlock * m, const char *funcName) 219 225 { 220 226 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 221 227 // we shouldn't call such things as p_psAlloc/p_psFree here. 222 228 223 if ( m == NULL) {224 psError( funcName, "Memory Corruption: NULL memory block found.");229 if (m == NULL) { 230 psError(funcName, "Memory Corruption: NULL memory block found."); 225 231 return 1; 226 232 } 227 233 228 if ( m->refCounter == 0) {234 if (m->refCounter == 0) { 229 235 // using an unreferenced block of memory, are you? 230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.", 231 m->id ); 236 psError(__func__, "Memory Corruption: memory block %ld was freed but still used.", m->id); 232 237 return 1; 233 238 } 234 239 235 if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) { 236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)", 237 m->id ); 240 if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) { 241 psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)", m->id); 238 242 return 1; 239 243 } 240 if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) { 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)", 242 m->id ); 244 if (*(void **)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) { 245 psError(funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)", m->id); 243 246 return 1; 244 247 } … … 247 250 } 248 251 249 int psMemCheckCorruption( bool abort_on_error)250 { 251 int nbad = 0; // number of bad blocks252 int psMemCheckCorruption(bool abort_on_error) 253 { 254 int nbad = 0; // number of bad blocks 252 255 253 256 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 254 pthread_mutex_lock( &memBlockListMutex);255 256 for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) {257 if ( checkMemBlock( iter, __func__ )) {257 pthread_mutex_lock(&memBlockListMutex); 258 259 for (psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) { 260 if (checkMemBlock(iter, __func__)) { 258 261 nbad++; 259 262 260 memProblemCallback( iter, __func__, __LINE__);261 262 if ( abort_on_error) {263 memProblemCallback(iter, __func__, __LINE__); 264 265 if (abort_on_error) { 263 266 // release the lock on the memblock list 264 pthread_mutex_unlock( &memBlockListMutex);265 psAbort( __func__, "Detected memory corruption");267 pthread_mutex_unlock(&memBlockListMutex); 268 psAbort(__func__, "Detected memory corruption"); 266 269 return nbad; 267 270 } … … 270 273 271 274 // release the lock on the memblock list 272 pthread_mutex_unlock( &memBlockListMutex);275 pthread_mutex_unlock(&memBlockListMutex); 273 276 return nbad; 274 277 } 275 278 276 void *p_psAlloc( size_t size, const char *file, int lineno)277 { 278 279 psMemBlock * ptr = NULL;279 void *p_psAlloc(size_t size, const char *file, int lineno) 280 { 281 282 psMemBlock *ptr = NULL; 280 283 281 284 // memory is of the size I want to bother recycling? 282 if ( size < P_PS_LARGE_BLOCK_SIZE) {285 if (size < P_PS_LARGE_BLOCK_SIZE) { 283 286 // find the bin we need. 284 287 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 288 289 while (size > recycleBinSize[level]) { 286 290 level++; 287 291 } 288 292 // Are we in one of the bins 289 if ( level < recycleBins) {290 291 size = recycleBinSize[ level]; // round-up size to next sized bin.292 293 pthread_mutex_lock( &recycleMemBlockListMutex);294 295 if ( recycleMemBlockList[ level ] != NULL) {296 ptr = recycleMemBlockList[ level];297 recycleMemBlockList[ level] = ptr->nextBlock;298 if ( recycleMemBlockList[ level ] != NULL) {299 recycleMemBlockList[ level ]->previousBlock = NULL;293 if (level < recycleBins) { 294 295 size = recycleBinSize[level]; // round-up size to next sized bin. 296 297 pthread_mutex_lock(&recycleMemBlockListMutex); 298 299 if (recycleMemBlockList[level] != NULL) { 300 ptr = recycleMemBlockList[level]; 301 recycleMemBlockList[level] = ptr->nextBlock; 302 if (recycleMemBlockList[level] != NULL) { 303 recycleMemBlockList[level]->previousBlock = NULL; 300 304 } 301 305 size = ptr->userMemorySize; 302 306 } 303 307 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 308 if ( ptr == NULL ) { 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 311 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 313 if ( ptr == NULL ) { 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 308 pthread_mutex_unlock(&recycleMemBlockListMutex); 309 } 310 } 311 312 if (ptr == NULL) { 313 ptr = malloc(sizeof(psMemBlock) + size + sizeof(void *)); 314 315 if (ptr == NULL) { 316 ptr = memExhaustedCallback(size); 317 if (ptr == NULL) { 318 psAbort(__func__, "Failed to allocate %u bytes at %s:%d", size, file, lineno); 316 319 } 317 320 } … … 320 323 ptr->endblock = P_PS_MEMMAGIC; 321 324 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 325 pthread_mutex_init(&ptr->refCounterMutex, NULL); 326 } 325 327 // increment the memory id safely. 326 pthread_mutex_lock( &memBlockListMutex);327 *( psMemoryId*) & ptr->id = ++memid;328 pthread_mutex_unlock( &memBlockListMutex);328 pthread_mutex_lock(&memBlockListMutex); 329 *(psMemoryId *) & ptr->id = ++memid; 330 pthread_mutex_unlock(&memBlockListMutex); 329 331 330 332 ptr->file = file; 331 333 ptr->freeFcn = NULL; 332 *( unsigned int* ) &ptr->lineno = lineno;333 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size) = P_PS_MEMMAGIC;334 *(unsigned int *)&ptr->lineno = lineno; 335 *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC; 334 336 ptr->previousBlock = NULL; 335 337 336 ptr->refCounter = 1; // one user so far338 ptr->refCounter = 1; // one user so far 337 339 338 340 // need exclusive access of the memory block list now... 339 pthread_mutex_lock( &memBlockListMutex);341 pthread_mutex_lock(&memBlockListMutex); 340 342 341 343 // insert the new block to the front of the memBlock linked-list 342 344 ptr->nextBlock = lastMemBlockAllocated; 343 if ( ptr->nextBlock != NULL) {345 if (ptr->nextBlock != NULL) { 344 346 ptr->nextBlock->previousBlock = ptr; 345 347 } 346 348 lastMemBlockAllocated = ptr; 347 349 348 pthread_mutex_unlock( &memBlockListMutex ); 349 350 // Did the user ask to be informed about this allocation? 351 if ( ptr->id == p_psMemAllocateID ) { 352 p_psMemAllocateID += memAllocateCallback( ptr ); 353 } 354 350 pthread_mutex_unlock(&memBlockListMutex); 351 352 // Did the user ask to be informed about this allocation? 353 if (ptr->id == p_psMemAllocateID) { 354 p_psMemAllocateID += memAllocateCallback(ptr); 355 } 355 356 // And return the user the memory that they allocated 356 return ptr + 1; // user memory357 } 358 359 void *p_psRealloc( void *vptr, size_t size, const char *file, int lineno)360 { 361 if ( vptr == NULL) {362 return p_psAlloc( size, file, lineno);357 return ptr + 1; // user memory 358 } 359 360 void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno) 361 { 362 if (vptr == NULL) { 363 return p_psAlloc(size, file, lineno); 363 364 } else { 364 psMemBlock *ptr = ( ( psMemBlock * ) vptr) - 1;365 psMemBlock *ptr = ((psMemBlock *) vptr) - 1; 365 366 bool isBlockLast = false; 366 367 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 368 memProblemCallback( ptr, file, lineno ); 369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).", 370 ptr->id, ptr->file, ptr->lineno ); 371 } 372 373 pthread_mutex_lock( &memBlockListMutex ); 374 375 isBlockLast = ( ptr == lastMemBlockAllocated ); 376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) ); 378 379 if ( ptr == NULL ) { 380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d", 381 size, file, lineno ); 368 if (checkMemBlock(ptr, __func__) != 0) { 369 memProblemCallback(ptr, file, lineno); 370 psAbort(file, "Realloc detected a memory corruption (id %ld @ %s:%d).", 371 ptr->id, ptr->file, ptr->lineno); 372 } 373 374 pthread_mutex_lock(&memBlockListMutex); 375 376 isBlockLast = (ptr == lastMemBlockAllocated); 377 378 ptr = (psMemBlock *) realloc(ptr, sizeof(psMemBlock) + size + sizeof(void *)); 379 380 if (ptr == NULL) { 381 psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d", size, file, lineno); 382 382 } 383 383 384 384 ptr->userMemorySize = size; 385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size) = P_PS_MEMMAGIC;386 387 if ( isBlockLast) {385 *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC; 386 387 if (isBlockLast) { 388 388 lastMemBlockAllocated = ptr; 389 389 } 390 391 390 // the block location may have changed, so fix the linked list addresses. 392 if ( ptr->nextBlock != NULL) {391 if (ptr->nextBlock != NULL) { 393 392 ptr->nextBlock->previousBlock = ptr; 394 393 } 395 if ( ptr->previousBlock != NULL) {394 if (ptr->previousBlock != NULL) { 396 395 ptr->previousBlock->nextBlock = ptr; 397 396 } 398 397 399 pthread_mutex_unlock( &memBlockListMutex);400 401 // Did the user ask to be informed about this allocation?402 if ( ptr->id == p_psMemAllocateID) {403 p_psMemAllocateID += memAllocateCallback( ptr);404 } 405 406 return ptr + 1; // usr memory407 } 408 } 409 410 void p_psFree( void *vptr, const char *file, int lineno)411 { 412 ( void ) p_psMemDecrRefCounter( vptr, file, lineno );// this handles the free, if required.398 pthread_mutex_unlock(&memBlockListMutex); 399 400 // Did the user ask to be informed about this allocation? 401 if (ptr->id == p_psMemAllocateID) { 402 p_psMemAllocateID += memAllocateCallback(ptr); 403 } 404 405 return ptr + 1; // usr memory 406 } 407 } 408 409 void p_psFree(void *vptr, const char *file, int lineno) 410 { 411 (void)p_psMemDecrRefCounter(vptr, file, lineno); // this handles the free, if required. 413 412 } 414 413 … … 416 415 * Check for memory leaks. 417 416 */ 418 int psMemCheckLeaks( psMemoryId id0, psMemBlock ***arr, FILE *fd)417 int psMemCheckLeaks(psMemoryId id0, psMemBlock *** arr, FILE * fd) 419 418 { 420 419 int nleak = 0; 421 420 int j = 0; 422 psMemBlock *topBlock = lastMemBlockAllocated;423 424 pthread_mutex_lock( &memBlockListMutex);425 426 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock) {427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 )) {421 psMemBlock *topBlock = lastMemBlockAllocated; 422 423 pthread_mutex_lock(&memBlockListMutex); 424 425 for (psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock) { 426 if ((psMemGetRefCounter(iter + 1) > 0) && (iter->id >= id0)) { 428 427 nleak++; 429 428 430 if ( fd != NULL) {431 if ( nleak == 1) {432 fprintf( fd, " %20s:line ID\n", "file");429 if (fd != NULL) { 430 if (nleak == 1) { 431 fprintf(fd, " %20s:line ID\n", "file"); 433 432 } 434 433 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);436 } 437 } 438 } 439 440 pthread_mutex_unlock( &memBlockListMutex);441 442 if ( nleak == 0 || arr == NULL) {434 fprintf(fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id); 435 } 436 } 437 } 438 439 pthread_mutex_unlock(&memBlockListMutex); 440 441 if (nleak == 0 || arr == NULL) { 443 442 return nleak; 444 443 } 445 444 446 *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__);447 pthread_mutex_lock( &memBlockListMutex);448 449 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock) {450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 )) {451 ( *arr ) [ j++] = iter;452 if ( j == nleak ) {// found them all445 *arr = p_psAlloc(nleak * sizeof(psMemBlock), __FILE__, __LINE__); 446 pthread_mutex_lock(&memBlockListMutex); 447 448 for (psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock) { 449 if ((psMemGetRefCounter(iter + 1) > 0) && (iter->id >= id0)) { 450 (*arr)[j++] = iter; 451 if (j == nleak) { // found them all 453 452 break; 454 453 } … … 456 455 } 457 456 458 pthread_mutex_unlock( &memBlockListMutex);457 pthread_mutex_unlock(&memBlockListMutex); 459 458 460 459 return nleak; … … 465 464 */ 466 465 // return refCounter 467 psReferenceCount psMemGetRefCounter( void *vptr)468 { 469 psMemBlock * ptr;466 psReferenceCount psMemGetRefCounter(void *vptr) 467 { 468 psMemBlock *ptr; 470 469 unsigned int refCount; 471 470 472 if ( vptr == NULL) {471 if (vptr == NULL) { 473 472 return 0; 474 473 } 475 474 476 ptr = ( ( psMemBlock * ) vptr) - 1;477 478 if ( checkMemBlock( ptr, __func__ ) != 0) {479 memProblemCallback( ptr, __func__, __LINE__);480 } 481 482 pthread_mutex_lock( &ptr->refCounterMutex);475 ptr = ((psMemBlock *) vptr) - 1; 476 477 if (checkMemBlock(ptr, __func__) != 0) { 478 memProblemCallback(ptr, __func__, __LINE__); 479 } 480 481 pthread_mutex_lock(&ptr->refCounterMutex); 483 482 refCount = ptr->refCounter; 484 pthread_mutex_unlock( &ptr->refCounterMutex);483 pthread_mutex_unlock(&ptr->refCounterMutex); 485 484 486 485 return refCount; 487 486 } 487 488 488 // increment and return refCounter 489 void * p_psMemIncrRefCounter( void *vptr, const char *file, int lineno)490 { 491 psMemBlock * ptr;492 493 if ( vptr == NULL) {489 void *p_psMemIncrRefCounter(void *vptr, const char *file, int lineno) 490 { 491 psMemBlock *ptr; 492 493 if (vptr == NULL) { 494 494 return vptr; 495 495 } 496 496 497 ptr = ( ( psMemBlock * ) vptr) - 1;498 499 if ( checkMemBlock( ptr, __func__ )) {500 memProblemCallback( ptr, file, lineno);501 } 502 503 pthread_mutex_lock( &ptr->refCounterMutex);497 ptr = ((psMemBlock *) vptr) - 1; 498 499 if (checkMemBlock(ptr, __func__)) { 500 memProblemCallback(ptr, file, lineno); 501 } 502 503 pthread_mutex_lock(&ptr->refCounterMutex); 504 504 ptr->refCounter++; 505 pthread_mutex_unlock( &ptr->refCounterMutex);505 pthread_mutex_unlock(&ptr->refCounterMutex); 506 506 507 507 return vptr; … … 509 509 510 510 // decrement and return refCounter 511 void * p_psMemDecrRefCounter( void *vptr, const char *file, int lineno)512 { 513 if ( vptr == NULL) {511 void *p_psMemDecrRefCounter(void *vptr, const char *file, int lineno) 512 { 513 if (vptr == NULL) { 514 514 return NULL; 515 515 } 516 516 517 psMemBlock *ptr = ( ( psMemBlock * ) vptr) - 1;518 519 if ( checkMemBlock( ptr, __func__ ) != 0) {520 memProblemCallback( ptr, file, lineno);517 psMemBlock *ptr = ((psMemBlock *) vptr) - 1; 518 519 if (checkMemBlock(ptr, __func__) != 0) { 520 memProblemCallback(ptr, file, lineno); 521 521 return NULL; 522 522 } 523 523 524 pthread_mutex_lock( &ptr->refCounterMutex);525 526 if ( ptr->refCounter > 1) {527 // / XXX - Probably should have another mutex here.528 ptr->refCounter--; // multiple references, just decrement the count.529 pthread_mutex_unlock( &ptr->refCounterMutex);524 pthread_mutex_lock(&ptr->refCounterMutex); 525 526 if (ptr->refCounter > 1) { 527 // / XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock(&ptr->refCounterMutex); 530 530 531 531 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex);532 pthread_mutex_unlock(&ptr->refCounterMutex); 533 533 534 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID) {536 p_psMemFreeID += memFreeCallback( ptr);537 } 538 539 if ( ptr->freeFcn != NULL) {540 ptr->freeFcn( vptr);541 } 542 543 pthread_mutex_lock( &memBlockListMutex);535 if (ptr->id == p_psMemFreeID) { 536 p_psMemFreeID += memFreeCallback(ptr); 537 } 538 539 if (ptr->freeFcn != NULL) { 540 ptr->freeFcn(vptr); 541 } 542 543 pthread_mutex_lock(&memBlockListMutex); 544 544 545 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL) {546 if (ptr->nextBlock != NULL) { 547 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 548 } 549 if ( ptr->previousBlock != NULL) {549 if (ptr->previousBlock != NULL) { 550 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 551 } 552 if ( lastMemBlockAllocated == ptr) {552 if (lastMemBlockAllocated == ptr) { 553 553 lastMemBlockAllocated = ptr->nextBlock; 554 554 } 555 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 556 pthread_mutex_unlock(&memBlockListMutex); 558 557 559 558 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) {559 if (ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) { 561 560 562 561 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 562 563 while (ptr->userMemorySize >= recycleBinSize[level]) { 564 564 level++; 565 565 } … … 569 569 ptr->previousBlock = NULL; 570 570 571 pthread_mutex_lock( &recycleMemBlockListMutex);572 ptr->nextBlock = recycleMemBlockList[ level];573 if ( recycleMemBlockList[ level ] != NULL) {574 recycleMemBlockList[ level ]->previousBlock = ptr;575 } 576 recycleMemBlockList[ level] = ptr;577 pthread_mutex_unlock( &recycleMemBlockListMutex);571 pthread_mutex_lock(&recycleMemBlockListMutex); 572 ptr->nextBlock = recycleMemBlockList[level]; 573 if (recycleMemBlockList[level] != NULL) { 574 recycleMemBlockList[level]->previousBlock = ptr; 575 } 576 recycleMemBlockList[level] = ptr; 577 pthread_mutex_unlock(&recycleMemBlockListMutex); 578 578 579 579 } else { 580 580 // memory is larger than I want to recycle. 581 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno);582 (void)p_psRealloc(vptr, 0, file, lineno); 583 583 ptr->previousBlock = NULL; 584 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL) {585 if (deadBlockList != NULL) { 586 586 deadBlockList->previous = ptr; 587 587 } … … 589 589 #else 590 590 591 pthread_mutex_destroy( &ptr->refCounterMutex);592 free( ptr);591 pthread_mutex_destroy(&ptr->refCounterMutex); 592 free(ptr); 593 593 #endif 594 594 595 595 } 596 596 597 vptr = NULL; // since we freed it, make sure we return NULL.597 vptr = NULL; // since we freed it, make sure we return NULL. 598 598 } 599 599 … … 601 601 } 602 602 603 void p_psMemSetDeallocator( void* vptr, psFreeFcn freeFcn)604 { 605 if ( vptr == NULL) {606 return ;607 } 608 609 psMemBlock *ptr = ( ( psMemBlock * ) vptr) - 1;610 611 if ( checkMemBlock( ptr, __func__ ) != 0) {612 memProblemCallback( ptr, __func__, __LINE__);603 void p_psMemSetDeallocator(void *vptr, psFreeFcn freeFcn) 604 { 605 if (vptr == NULL) { 606 return; 607 } 608 609 psMemBlock *ptr = ((psMemBlock *) vptr) - 1; 610 611 if (checkMemBlock(ptr, __func__) != 0) { 612 memProblemCallback(ptr, __func__, __LINE__); 613 613 } 614 614 … … 616 616 617 617 } 618 psFreeFcn p_psMemGetDeallocator( void* vptr)619 { 620 if ( vptr == NULL) {618 psFreeFcn p_psMemGetDeallocator(void *vptr) 619 { 620 if (vptr == NULL) { 621 621 return NULL; 622 622 } 623 623 624 psMemBlock *ptr = ( ( psMemBlock * ) vptr) - 1;625 626 if ( checkMemBlock( ptr, __func__ ) != 0) {627 memProblemCallback( ptr, __func__, __LINE__);624 psMemBlock *ptr = ((psMemBlock *) vptr) - 1; 625 626 if (checkMemBlock(ptr, __func__) != 0) { 627 memProblemCallback(ptr, __func__, __LINE__); 628 628 } 629 629
Note:
See TracChangeset
for help on using the changeset viewer.
