Changeset 31575
- Timestamp:
- May 26, 2011, 5:50:58 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110505/psLib/src/sys/psMemory.c
r31574 r31575 332 332 333 333 // if HARDLOCKS is set, revert to global locking for realloc 334 # define HARDLOCKS 1 334 # define HARDLOCKS 0 335 336 # if (!HARDLOCKS) 337 static int setLock1 = 0; 338 static int clearLock1 = 0; 339 340 static int setLock2 = 0; 341 static int clearLock2 = 0; 342 343 static int setLockNext = 0; 344 static int clearLockNext = 0; 345 346 static int setLockPrev = 0; 347 static int clearLockPrev = 0; 348 # endif 349 350 # define BLOCK_SLEEP 100 351 352 static int callL1 = 0; 353 static int callL2 = 0; 354 355 # define MEM_ASSERT(COND,MSG) { if (!(COND)) { fprintf (stderr, MSG); abort(); } } 356 357 // pointer to the last mem block that was allocated. 358 // This is the root of the entire memory list 359 static psMemBlock *lastMemBlockAllocated = NULL; 360 361 // set lock on lastMemBlockAllocated 362 void BLOCKLAST_LOCK () { 363 364 # if (HARDLOCKS) 365 MUTEX_LOCK(&memBlockListMutex); 366 # else 367 368 // if memBlock is not defined, we are just asking for a m 369 if (!lastMemBlockAllocated) { 370 MUTEX_LOCK(&memBlockListMutex); 371 return; 372 } 373 374 while (true) { 375 // we cannot set the lock on the marker while the lock is held 376 while (lastMemBlockAllocated->inFlight) { usleep (BLOCK_SLEEP); } 377 378 // set a lock, then lock this memblock and its neighbors 379 MUTEX_LOCK(&memBlockListMutex); 380 381 // did we beat the race condition? is the lock still clear? 382 if (lastMemBlockAllocated->inFlight) { 383 // nope, we need to try again 384 MUTEX_UNLOCK(&memBlockListMutex); 385 continue; 386 } 387 388 // the marker is ours! 389 lastMemBlockAllocated->inFlight = true; 390 setLock1 ++; 391 return; 392 } 393 # endif 394 } 335 395 336 396 // memBlock->inFlight is a 'soft' lock. if true, the lock is set … … 341 401 # else 342 402 343 psAssert (memBlock || keepMutex, "trying to set a soft lock on a non-existent memBlock");403 MEM_ASSERT (memBlock || keepMutex, "trying to set a soft lock on a non-existent memBlock\n"); 344 404 345 405 // if memBlock is not defined, we are just asking for a m … … 351 411 while (true) { 352 412 // we cannot set the lock on the marker while the lock is held 353 while (memBlock->inFlight) { usleep ( 10000); }413 while (memBlock->inFlight) { usleep (BLOCK_SLEEP); } 354 414 355 415 // set a lock, then lock this memblock and its neighbors … … 365 425 // the marker is ours! 366 426 memBlock->inFlight = true; 427 setLock1 ++; 367 428 if (keepMutex) return; 368 429 … … 379 440 # else 380 441 381 psAssert (memBlock || haveMutex, "trying to clear a soft lock on a non-existent memBlock");442 MEM_ASSERT (memBlock || haveMutex, "trying to clear a soft lock on a non-existent memBlock\n"); 382 443 383 444 // if memBlock is not defined, we are just asking for a regular lock … … 387 448 } 388 449 450 MEM_ASSERT (memBlock->inFlight, "trying to clear an unlocked memBlock\n"); 451 389 452 // need to lock before clearing the marker 390 453 if (!haveMutex) { … … 392 455 } 393 456 memBlock->inFlight = false; 457 clearLock1 ++; 394 458 MUTEX_UNLOCK(&memBlockListMutex); 395 459 return; … … 406 470 # else 407 471 408 psAssert (memBlock, "trying to set a soft lock on a non-existent memBlock");472 MEM_ASSERT (memBlock, "trying to set a soft lock on a non-existent memBlock\n"); 409 473 410 474 while (true) { 411 475 // we cannot set the lock on the marker while the lock is held 412 476 // wait until all three markers are clear: 413 while (memBlock->inFlight) { usleep (10000); } 414 if (memBlock->nextBlock) { 415 while (memBlock->nextBlock->inFlight) { usleep (10000); } 416 } 417 if (memBlock->previousBlock) { 418 while (memBlock->previousBlock->inFlight) { usleep (10000); } 419 } 477 while (memBlock->inFlight) { usleep (BLOCK_SLEEP); } 478 while (memBlock->nextBlock && memBlock->nextBlock->inFlight) { usleep (BLOCK_SLEEP); } 479 while (memBlock->previousBlock && memBlock->previousBlock->inFlight) { usleep (BLOCK_SLEEP); } 420 480 421 481 // set a lock, then lock this memblock and its neighbors … … 441 501 // the markers are ours! 442 502 memBlock->inFlight = true; 503 setLock2 ++; 443 504 if (memBlock->nextBlock) { 444 505 memBlock->nextBlock->inFlight = true; 506 setLockNext ++; 445 507 } 446 508 if (memBlock->previousBlock) { 447 509 memBlock->previousBlock->inFlight = true; 510 setLockPrev ++; 448 511 } 449 512 if (keepMutex) return; … … 465 528 MUTEX_LOCK(&memBlockListMutex); 466 529 } 530 MEM_ASSERT (memBlock->inFlight, "trying to clear an unlocked memBlock\n"); 467 531 memBlock->inFlight = false; 532 clearLock2 ++; 468 533 if (memBlock->nextBlock) { 534 MEM_ASSERT (memBlock->nextBlock->inFlight, "trying to clear an unlocked memBlock\n"); 469 535 memBlock->nextBlock->inFlight = false; 536 clearLockNext ++; 470 537 } 471 538 if (memBlock->previousBlock) { 539 MEM_ASSERT (memBlock->previousBlock->inFlight, "trying to clear an unlocked memBlock\n"); 472 540 memBlock->previousBlock->inFlight = false; 541 clearLockPrev ++; 473 542 } 474 543 MUTEX_UNLOCK(&memBlockListMutex); … … 476 545 # endif 477 546 } 478 479 // pointer to the last mem block that was allocated.480 // This is the root of the entire memory list481 static psMemBlock *lastMemBlockAllocated = NULL;482 547 483 548 /* Actually allocate memory … … 549 614 memBlock->refCounter = 1; // one user so far 550 615 616 psMemBlock *last0 = lastMemBlockAllocated; 617 int flight0 = (lastMemBlockAllocated) ? lastMemBlockAllocated->inFlight : 10; 618 551 619 // need exclusive access of the memory block list now... 552 620 // this lock is very frequently called in a given program 553 621 // lastMemBlockAllocated is always true except the first allocation 554 BLOCK_LOCK (lastMemBlockAllocated, true); 622 BLOCKLAST_LOCK (); 623 callL1++; 624 625 psMemBlock *last1 = lastMemBlockAllocated; 626 int flight1 = (lastMemBlockAllocated) ? lastMemBlockAllocated->inFlight : 10; 627 628 if (false) { 629 fprintf (stderr, "last 0 : %lld, last 1 : %lld, flight0: %d, flight1: %d\n", (long long int) last0, (long long int) last1, (int) flight0, (int) flight1); 630 } 555 631 556 632 // increment the memory id only after we've grabbed the memBlockListMutex this value is … … 573 649 574 650 BLOCK_UNLOCK (memBlock->nextBlock, true); 651 callL1--; 652 653 // if (callL1 > +7) abort(); 654 // if (callL1 < -7) abort(); 575 655 576 656 // And return the user the memory that they allocated … … 720 800 // set a lock, then lock this memblock and its neighbors. at the end of this call, 721 801 // the global mutex is released, but the memBlock and its neighbors are protected 722 BLOCKSET_LOCK (memBlock, false);723 //MUTEX_LOCK(&memBlockListMutex);802 // BLOCKSET_LOCK (memBlock, false); 803 MUTEX_LOCK(&memBlockListMutex); 724 804 725 805 psMemBlock *nextBlock = memBlock->nextBlock; … … 767 847 768 848 // all of the list modifications are done; set the lock and clear the per-memBlock locks 769 // MUTEX_UNLOCK(&memBlockListMutex); 770 BLOCKSET_UNLOCK(memBlock, false); 771 772 psAssert (!memBlock->inFlight, "unreleased lock?"); 773 psAssert (!nextBlock || !nextBlock->inFlight, "unreleased lock?"); 774 psAssert (!previousBlock || !previousBlock->inFlight, "unreleased lock?"); 849 // BLOCKSET_UNLOCK(memBlock, false); 850 MUTEX_UNLOCK(&memBlockListMutex); 851 852 // XXX these are not actually guaranteed : another thread may already grab them before we get here 853 // psAssert (!memBlock->inFlight, "unreleased lock?"); 854 // psAssert (!nextBlock || !nextBlock->inFlight, "unreleased lock?"); 855 // psAssert (!previousBlock || !previousBlock->inFlight, "unreleased lock?"); 775 856 776 857 return memBlock + 1; // usr memory … … 999 1080 // we need a MUTEX_LOCK here: otherwise, two functions can race on refCounter--; 1000 1081 BLOCK_LOCK (memBlock, true); 1082 callL2++; 1001 1083 if (memBlock->refCounter > 1) { 1002 1084 memBlock->refCounter--; … … 1007 1089 } 1008 1090 BLOCK_UNLOCK(memBlock, true); 1091 callL2--; 1009 1092 return ptr; 1010 1093 } 1011 1094 BLOCK_UNLOCK(memBlock, true); 1095 callL2--; 1096 // if (callL2 > +7) abort(); 1097 // if (callL2 < -7) abort(); 1012 1098 1013 1099 // we can't invoke freeFunc() while we're holding memBlockListMutex as it … … 1041 1127 BLOCKSET_UNLOCK (memBlock, true); 1042 1128 1129 // XXX keep this? 1130 psAssert (memBlock->nextBlock == nextBlock, "unexpected rearrangement"); 1131 psAssert (memBlock->previousBlock == previousBlock, "unexpected rearrangement"); 1132 1043 1133 // NULL out the refs so no one can get confused 1044 1134 memBlock->nextBlock = NULL; 1045 1135 memBlock->previousBlock = NULL; 1046 1136 1047 // XXX these are slightly dangerous : someone else may grab the lock in the meanwhile...1048 psAssert (!memBlock->inFlight, "unreleased lock?");1049 psAssert (!nextBlock || !nextBlock->inFlight, "unreleased lock?");1050 psAssert (!previousBlock || !previousBlock->inFlight, "unreleased lock?");1137 // XXX these are not actually guaranteed : another thread may already grab them before we get here 1138 // psAssert (!memBlock->inFlight, "unreleased lock?"); 1139 // psAssert (!nextBlock || !nextBlock->inFlight, "unreleased lock?"); 1140 // psAssert (!previousBlock || !previousBlock->inFlight, "unreleased lock?"); 1051 1141 1052 1142 // invoke free only after we've released the block list lock as free()
Note:
See TracChangeset
for help on using the changeset viewer.
