Changeset 8809 for trunk/psLib/src/sys/psMemory.c
- Timestamp:
- Sep 13, 2006, 11:14:48 AM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sys/psMemory.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sys/psMemory.c
r8808 r8809 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.8 3$ $Name: not supported by cvs2svn $11 * @date $Date: 2006-09-13 21:1 1:11$10 * @version $Revision: 1.84 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2006-09-13 21:14:48 $ 12 12 * 13 13 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 38 38 #define P_PS_MEMMAGIC (psPtr )0xdeadbeef // Magic number in psMemBlock header 39 39 40 #define P_PS_LARGE_BLOCK_SIZE 65536 // size where under, we try to recycle 40 41 41 42 static psS32 checkMemBlock(const psMemBlock* m, const char *funcName); … … 50 51 static bool memory_is_persistent = false; 51 52 53 #ifdef PS_MEM_USE_RECYCLE // Only use recycling if this is set 54 #define N_RECYCLE_BINS 14 // number of recycle bins 55 #define MAX_RECYCLE 100 // Maximum number permitted in a recycle bin 56 static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER; // Mutex for recycle bins 57 static const psS32 recycleBinSize[N_RECYCLE_BINS] = // Size of each bin 58 { 59 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE 60 }; 61 // N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops) 62 static psS32 recycleBinNums[N_RECYCLE_BINS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Number in each bin 63 static psMemBlock* recycleMemBlockList[N_RECYCLE_BINS] = // Contents of the bins 64 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 65 #endif // #ifdef PS_MEM_USE_RECYCLE 66 52 67 #ifdef PS_MEM_DEBUG 53 68 static psMemBlock* deadBlockList; // a place to put dead memBlocks in debug mode. … … 58 73 */ 59 74 static psMemId memid = 0; 75 76 /** 77 * Default memExhausted callback. 78 */ 79 static psPtr memExhaustedCallbackDefault(size_t size) 80 { 81 #if PS_MEM_USE_RECYCLE 82 psPtr ptr = NULL; 83 if (safeThreads) { 84 pthread_mutex_lock(&recycleMemBlockListMutex); 85 } 86 // Attempt to free up everything I can find so I can alloc my ptr 87 int bin = N_RECYCLE_BINS - 1; // Recycle bin 88 89 while (bin >= 0 && ptr == NULL) { 90 while (recycleMemBlockList[bin] != NULL && ptr == NULL) { 91 psMemBlock *old = recycleMemBlockList[bin]; 92 recycleMemBlockList[bin] = recycleMemBlockList[bin]->nextBlock; 93 free(old); 94 ptr = malloc(size); 95 } 96 bin--; 97 } 98 99 if (safeThreads) { 100 pthread_mutex_unlock(&recycleMemBlockListMutex); 101 } 102 return ptr; 103 #else // #ifdef PS_MEM_USE_RECYCLE 104 105 return NULL; 106 #endif // #ifdef PS_MEM_USE_RECYCLE 107 } 60 108 61 109 /* … … 102 150 const char *funcName) 103 151 { 104 // n.b. since this is called by psMemCheckCorruption while the memblock 105 // list is mutex locked, we shouldn't call such things as 106 // p_psAlloc/p_psFree here. 152 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 153 // we shouldn't call such things as p_psAlloc/p_psFree here. 107 154 108 155 if (m == NULL) { … … 142 189 static psMemFreeCallback memFreeCallback = memFreeCallbackDefault; 143 190 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault; 191 static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault; 192 193 psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func) 194 { 195 psMemExhaustedCallback old = memExhaustedCallback; 196 197 if (func != NULL) { 198 memExhaustedCallback = func; 199 } else { 200 memExhaustedCallback = memExhaustedCallbackDefault; 201 } 202 203 return old; 204 } 144 205 145 206 psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func) … … 216 277 217 278 if (safeThreads) { 218 // LOCK: id219 279 pthread_mutex_lock(&memIdMutex); 220 280 } … … 223 283 224 284 if (safeThreads) { 225 // UNLOCK: id226 285 pthread_mutex_unlock(&memIdMutex); 227 286 } … … 232 291 psMemId psMemGetLastId(void) 233 292 { 234 psMemId id; 235 236 if (safeThreads) { 237 // LOCK: id 238 pthread_mutex_lock(&memIdMutex); 239 } 240 241 id = memid; 242 243 if (safeThreads) { 244 // UNLOCK: id 245 pthread_mutex_unlock(&memIdMutex); 246 } 247 248 return id; 293 return memid; 249 294 } 250 295 … … 252 297 { 253 298 psS32 nbad = 0; // number of bad blocks 254 255 // get exclusive access to the memBlock list to avoid it changing on us 256 // while we use it. 257 if (safeThreads) { 258 // LOCK: block list 259 pthread_mutex_unlock(&memBlockListMutex); 260 } 299 psBool failure = false; 300 301 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 302 // pthread_mutex_lock(&memBlockListMutex); 261 303 262 304 for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) { 263 if (checkMemBlock(iter, __func__)) { 305 if (safeThreads) { 306 pthread_mutex_unlock(&memBlockListMutex); 307 } 308 failure = checkMemBlock(iter, __func__); 309 if (safeThreads) { 310 pthread_mutex_lock(&memBlockListMutex); 311 } 312 if ( failure ) { 264 313 nbad++; 265 314 … … 267 316 268 317 if (abort_on_error) { 318 // release the lock on the memblock list 269 319 if (safeThreads) { 270 // UNLOCK: block list271 320 pthread_mutex_unlock(&memBlockListMutex); 272 321 } … … 277 326 } 278 327 279 if (safeThreads) {280 // UNLOCK: block list328 // release the lock on the memblock list 329 if (safeThreads) { 281 330 pthread_mutex_unlock(&memBlockListMutex); 282 331 } 283 284 332 return nbad; 285 333 } … … 379 427 psMemBlock *ptr = NULL; 380 428 429 #ifdef PS_MEM_USE_RECYCLE 430 // Are we in one of the recycle bins? 431 int bin = getRecycleBin(size); 432 if (bin < N_RECYCLE_BINS) { 433 size = recycleBinSize[bin]; // round-up size to next sized bin. 434 ptr = recyclePop(bin); // grab out of the recycle bin 435 } 436 #endif // #ifdef PS_MEM_USE_RECYCLE 437 381 438 if (ptr == NULL) { 382 439 ptr = malloc(sizeof(psMemBlock) + size + sizeof(psPtr )); 383 440 384 441 if (ptr == NULL) { 385 psAbort(__func__, "Failed to allocate %zd bytes at %s:%d", size, file, lineno); 442 ptr = memExhaustedCallback(size); 443 if (ptr == NULL) { 444 psAbort(__func__, "Failed to allocate %zd bytes at %s:%d", size, file, lineno); 445 } 386 446 } 387 447 … … 473 533 ptr = (psMemBlock *)realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr)); 474 534 if (ptr == NULL) { 475 psAbort(__func__, "Failed to reallocate %zd bytes at %s:%d", size, file, lineno); 535 ptr = memExhaustedCallback(size); 536 if (ptr == NULL) { 537 psAbort(__func__, "Failed to reallocate %zd bytes at %s:%d", size, file, lineno); 538 } 476 539 } 477 540
Note:
See TracChangeset
for help on using the changeset viewer.
