- Timestamp:
- Apr 3, 2013 9:47:49 AM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectBoth.cpp
r45152 r45299 45 45 || pVCpu->pdm.s.cQueuedCritSectRwExclLeaves > 0); 46 46 47 #if 0 /* Later... */48 47 /* Shared leaves. */ 49 48 i = pVCpu->pdm.s.cQueuedCritSectRwShrdLeaves; … … 58 57 # endif 59 58 60 PDMCritSectRwLeaveShared(pCritSectRw);59 pdmCritSectRwLeaveSharedQueued(pCritSectRw); 61 60 LogFlow(("PDMR3CritSectFF: %p (R/W)\n", pCritSectRw)); 62 61 } … … 74 73 # endif 75 74 76 PDMCritSectRwLeaveExcl(pCritSectRw);75 pdmCritSectRwLeaveExclQueued(pCritSectRw); 77 76 LogFlow(("PDMR3CritSectFF: %p (R/W)\n", pCritSectRw)); 78 77 } 79 #endif80 78 81 79 /* Normal leaves. */ -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r45293 r45299 80 80 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf(); 81 81 #else 82 AssertMsgReturn(pThis->s.Core.u32Magic == RTCRITSECT _MAGIC, ("%RX32\n", pThis->s.Core.u32Magic),82 AssertMsgReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, ("%RX32\n", pThis->s.Core.u32Magic), 83 83 NIL_RTNATIVETHREAD); 84 84 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); … … 123 123 124 124 125 static int pdmCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly) 125 /** 126 * Worker that enters a read/write critical section with shard access. 127 * 128 * @returns VBox status code. 129 * @param pThis Pointer to the read/write critical section. 130 * @param rcBusy The busy return code for ring-0 and ring-3. 131 * @param fTryOnly Only try enter it, don't wait. 132 * @param pSrcPos The source position. (Can be NULL.) 133 * @param fNoVal No validation records. 134 */ 135 static int pdmCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly, PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal) 126 136 { 127 137 /* … … 166 176 { 167 177 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 168 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 178 if (!fNoVal) 179 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 169 180 #endif 170 181 break; … … 180 191 Assert(!pThis->s.Core.fNeedReset); 181 192 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 182 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 193 if (!fNoVal) 194 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 183 195 #endif 184 196 break; … … 194 206 { 195 207 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 196 int rc9 = RTLockValidatorRecExclRecursionMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core, pSrcPos); 197 if (RT_FAILURE(rc9)) 198 return rc9; 208 if (!fNoVal) 209 { 210 int rc9 = RTLockValidatorRecExclRecursionMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core, pSrcPos); 211 if (RT_FAILURE(rc9)) 212 return rc9; 213 } 199 214 #endif 200 215 Assert(pThis->s.Core.cWriterReads < UINT32_MAX / 2); 201 216 ASMAtomicIncU32(&pThis->s.Core.cWriterReads); 217 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterShared)); 202 218 return VINF_SUCCESS; /* don't break! */ 203 219 } 204 220 205 /* If we're only trying, return already. */ 221 /* 222 * If we're only trying, return already. 223 */ 206 224 if (fTryOnly) 225 { 226 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterShared)); 207 227 return VERR_SEM_BUSY; 228 } 208 229 209 230 #if defined(IN_RING3) … … 299 320 300 321 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 301 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 322 if (!fNoVal) 323 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 302 324 # endif 303 325 break; … … 309 331 * back to ring-3 and do it there or return rcBusy. 310 332 */ 333 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterShared)); 311 334 if (rcBusy == VINF_SUCCESS) 312 335 { … … 362 385 { 363 386 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 364 return pdmCritSectRwEnterShared(pThis, rcBusy, NULL, false /*fTryOnly*/);387 return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, NULL, false /*fNoVal*/); 365 388 #else 366 389 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 367 return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/);390 return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, &SrcPos, false /*fNoVal*/); 368 391 #endif 369 392 } … … 395 418 { 396 419 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 397 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, false /*fTryOnly*/);420 return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, NULL, false /*fNoVal*/); 398 421 #else 399 422 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 400 return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/);423 return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, &SrcPos, false /*fNoVal*/); 401 424 #endif 402 425 } … … 425 448 { 426 449 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 427 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, true /*fTryOnly*/);450 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, true /*fTryOnly*/, NULL, false /*fNoVal*/); 428 451 #else 429 452 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 430 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryOnly*/);453 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, true /*fTryOnly*/, &SrcPos, false /*fNoVal*/); 431 454 #endif 432 455 } … … 455 478 { 456 479 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 457 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, true /*fTryOnly*/);480 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, true /*fTryOnly*/, NULL, false /*fNoVal*/); 458 481 #else 459 482 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 460 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryOnly*/);483 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, true /*fTryOnly*/, &SrcPos, false /*fNoVal*/); 461 484 #endif 462 485 } … … 476 499 VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3) 477 500 { 478 int rc = pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, false /*fTryAgain*/); 479 if ( rc == VINF_SUCCESS 480 && fCallRing3 481 && pThis->s.Core.pValidatorRead) 482 { 483 Assert(pThis->s.Core.pValidatorWrite); 484 if (pThis->s.Core.hNativeWriter == NIL_RTNATIVETHREAD) 485 RTLockValidatorRecSharedCheckAndRelease(pThis->s.Core.pValidatorRead, NIL_RTTHREAD); 486 else 487 RTLockValidatorRecExclUnwindMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core); 488 } 489 return rc; 490 } 491 #endif /* IN_RING3 */ 501 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, false /*fTryAgain*/, fCallRing3); 502 } 503 #endif 492 504 493 505 … … 498 510 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 499 511 * during the operation. 500 * @param pThis Pointer to the read/write critical section. 512 * @param pThis Pointer to the read/write critical section. 513 * @param fNoVal No validation records (i.e. queued release). 501 514 * @sa PDMCritSectRwEnterShared, PDMCritSectRwTryEnterShared, 502 515 * PDMCritSectRwEnterSharedDebug, PDMCritSectRwTryEnterSharedDebug, 503 516 * PDMCritSectRwLeaveExcl, RTCritSectRwLeaveShared. 504 517 */ 505 VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pThis)518 static int pdmCritSectRwLeaveSharedWorker(PPDMCRITSECTRW pThis, bool fNoVal) 506 519 { 507 520 /* … … 519 532 { 520 533 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 521 int rc9 = RTLockValidatorRecSharedCheckAndRelease(pThis->s.Core.pValidatorRead, NIL_RTTHREAD); 522 if (RT_FAILURE(rc9)) 523 return rc9; 534 if (fNoVal) 535 Assert(!RTLockValidatorRecSharedIsOwner(pThis->s.Core.pValidatorRead, NIL_RTTHREAD)); 536 else 537 { 538 int rc9 = RTLockValidatorRecSharedCheckAndRelease(pThis->s.Core.pValidatorRead, NIL_RTTHREAD); 539 if (RT_FAILURE(rc9)) 540 return rc9; 541 } 524 542 #endif 525 543 for (;;) … … 578 596 AssertReturn(pThis->s.Core.cWriterReads > 0, VERR_NOT_OWNER); 579 597 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 580 int rc = RTLockValidatorRecExclUnwindMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core); 581 if (RT_FAILURE(rc)) 582 return rc; 598 if (!fNoVal) 599 { 600 int rc = RTLockValidatorRecExclUnwindMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core); 601 if (RT_FAILURE(rc)) 602 return rc; 603 } 583 604 #endif 584 605 ASMAtomicDecU32(&pThis->s.Core.cWriterReads); … … 588 609 } 589 610 590 591 static int pdmCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly) 611 /** 612 * Leave a critical section held with shared access. 613 * 614 * @returns VBox status code. 615 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 616 * during the operation. 617 * @param pThis Pointer to the read/write critical section. 618 * @sa PDMCritSectRwEnterShared, PDMCritSectRwTryEnterShared, 619 * PDMCritSectRwEnterSharedDebug, PDMCritSectRwTryEnterSharedDebug, 620 * PDMCritSectRwLeaveExcl, RTCritSectRwLeaveShared. 621 */ 622 VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pThis) 623 { 624 return pdmCritSectRwLeaveSharedWorker(pThis, false /*fNoVal*/); 625 } 626 627 628 #if defined(IN_RING3) || defined(IN_RING0) 629 /** 630 * PDMCritSectBothFF interface. 631 * 632 * @param pThis Pointer to the read/write critical section. 633 */ 634 void pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis) 635 { 636 pdmCritSectRwLeaveSharedWorker(pThis, true /*fNoVal*/); 637 } 638 #endif 639 640 641 /** 642 * Worker that enters a read/write critical section with exclusive access. 643 * 644 * @returns VBox status code. 645 * @param pThis Pointer to the read/write critical section. 646 * @param rcBusy The busy return code for ring-0 and ring-3. 647 * @param fTryOnly Only try enter it, don't wait. 648 * @param pSrcPos The source position. (Can be NULL.) 649 * @param fNoVal No validation records. 650 */ 651 static int pdmCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly, PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal) 592 652 { 593 653 /* … … 618 678 Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)); 619 679 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 620 int rc9 = RTLockValidatorRecExclRecursion(pThis->s.Core.pValidatorWrite, pSrcPos); 621 if (RT_FAILURE(rc9)) 622 return rc9; 680 if (!fNoVal) 681 { 682 int rc9 = RTLockValidatorRecExclRecursion(pThis->s.Core.pValidatorWrite, pSrcPos); 683 if (RT_FAILURE(rc9)) 684 return rc9; 685 } 623 686 #endif 624 687 Assert(pThis->s.Core.cWriteRecursions < UINT32_MAX / 2); … … 657 720 } 658 721 else if (fTryOnly) 722 { 659 723 /* Wrong direction and we're not supposed to wait, just return. */ 724 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterExcl)); 660 725 return VERR_SEM_BUSY; 726 } 661 727 else 662 728 { … … 693 759 if (!fDone) 694 760 { 761 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterExcl)); 762 695 763 #if defined(IN_RING3) 696 /* 697 * Wait for our turn. 698 */ 699 for (uint32_t iLoop = 0; ; iLoop++) 700 { 701 int rc; 764 if (!fTryOnly) 765 { 766 /* 767 * Wait for our turn. 768 */ 769 for (uint32_t iLoop = 0; ; iLoop++) 770 { 771 int rc; 702 772 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 703 if (!fTryOnly)704 {705 773 if (hThreadSelf == NIL_RTTHREAD) 706 774 hThreadSelf = RTThreadSelfAutoAdopt(); 707 775 rc = RTLockValidatorRecExclCheckBlocking(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true, 708 776 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_WRITE, false); 709 } 710 else 711 rc = VINF_SUCCESS; 712 if (RT_SUCCESS(rc)) 777 if (RT_SUCCESS(rc)) 713 778 # else 714 RTTHREAD hThreadSelf = RTThreadSelf();715 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false);779 RTTHREAD hThreadSelf = RTThreadSelf(); 780 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false); 716 781 # endif 717 {718 do719 rc = SUPSemEventWaitNoResume(pThis->s.CTX_SUFF(pVM)->pSession,720 (SUPSEMEVENT)pThis->s.Core.hEvtWrite,721 RT_INDEFINITE_WAIT);722 while (rc == VERR_INTERRUPTED && pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC);723 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE);724 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC)725 return VERR_SEM_DESTROYED;726 }727 if (RT_FAILURE(rc))728 {729 /* Decrement the counts and return the error. */730 for (;;)731 782 { 732 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 733 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0); 734 c--; 735 u64State &= ~RTCSRW_CNT_WR_MASK; 736 u64State |= c << RTCSRW_CNT_WR_SHIFT; 737 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 783 do 784 rc = SUPSemEventWaitNoResume(pThis->s.CTX_SUFF(pVM)->pSession, 785 (SUPSEMEVENT)pThis->s.Core.hEvtWrite, 786 RT_INDEFINITE_WAIT); 787 while (rc == VERR_INTERRUPTED && pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC); 788 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 789 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 790 return VERR_SEM_DESTROYED; 791 } 792 if (RT_FAILURE(rc)) 793 { 794 /* Decrement the counts and return the error. */ 795 for (;;) 796 { 797 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 798 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0); 799 c--; 800 u64State &= ~RTCSRW_CNT_WR_MASK; 801 u64State |= c << RTCSRW_CNT_WR_SHIFT; 802 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 803 break; 804 } 805 return rc; 806 } 807 808 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 809 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 810 { 811 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 812 if (fDone) 738 813 break; 739 814 } 740 return rc;815 AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */ 741 816 } 742 817 743 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 744 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 818 } 819 else 820 #endif /* IN_RING3 */ 821 { 822 #ifdef IN_RING3 823 /* TryEnter call - decrement the number of (waiting) writers. */ 824 #else 825 /* We cannot call SUPSemEventWaitNoResume in this context. Go back to 826 ring-3 and do it there or return rcBusy. */ 827 #endif 828 829 for (;;) 745 830 { 746 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 747 if (fDone) 831 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 832 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0); 833 c--; 834 u64State &= ~RTCSRW_CNT_WR_MASK; 835 u64State |= c << RTCSRW_CNT_WR_SHIFT; 836 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 748 837 break; 749 838 } 750 AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */ 751 } 752 753 #else 754 /* We cannot call SUPSemEventWaitNoResume in this context. Go back to 755 ring-3 and do it there or return rcBusy. */ 756 for (;;) 757 { 758 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 759 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0); 760 c--; 761 u64State &= ~RTCSRW_CNT_WR_MASK; 762 u64State |= c << RTCSRW_CNT_WR_SHIFT; 763 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 764 break; 765 } 766 767 if (rcBusy == VINF_SUCCESS) 768 { 769 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 770 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 771 /** @todo Should actually do this in via VMMR0.cpp instead of going all the way 772 * back to ring-3. Goes for both kind of crit sects. */ 773 return VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL, MMHyperCCToR3(pVM, pThis)); 774 } 775 return rcBusy; 776 777 #endif 839 840 #ifdef IN_RING3 841 return VERR_SEM_BUSY; 842 #else 843 if (rcBusy == VINF_SUCCESS) 844 { 845 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 846 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 847 /** @todo Should actually do this in via VMMR0.cpp instead of going all the way 848 * back to ring-3. Goes for both kind of crit sects. */ 849 return VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL, MMHyperCCToR3(pVM, pThis)); 850 } 851 return rcBusy; 852 #endif 853 } 778 854 } 779 855 … … 785 861 Assert(pThis->s.Core.cWriterReads == 0); 786 862 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 787 RTLockValidatorRecExclSetOwner(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true); 863 if (!fNoVal) 864 RTLockValidatorRecExclSetOwner(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true); 788 865 #endif 789 866 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterExcl)); … … 816 893 { 817 894 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 818 return pdmCritSectRwEnterExcl(pThis, rcBusy, NULL, false /*fTryAgain*/);895 return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, NULL, false /*fNoVal*/); 819 896 #else 820 897 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 821 return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/);898 return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, &SrcPos, false /*fNoVal*/); 822 899 #endif 823 900 } … … 850 927 { 851 928 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 852 return pdmCritSectRwEnterExcl(pThis, rcBusy, NULL, false /*fTryAgain*/);929 return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, NULL, false /*fNoVal*/); 853 930 #else 854 931 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 855 return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/);932 return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, &SrcPos, false /*fNoVal*/); 856 933 #endif 857 934 } … … 876 953 { 877 954 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 878 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, true /*fTryAgain*/);955 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, true /*fTryAgain*/, NULL, false /*fNoVal*/); 879 956 #else 880 957 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 881 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryAgain*/);958 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, true /*fTryAgain*/, &SrcPos, false /*fNoVal*/); 882 959 #endif 883 960 } … … 906 983 { 907 984 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 908 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, true /*fTryAgain*/);985 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, true /*fTryAgain*/, NULL, false /*fNoVal*/); 909 986 #else 910 987 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 911 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryAgain*/);988 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, true /*fTryAgain*/, &SrcPos, false /*fNoVal*/); 912 989 #endif 913 990 } … … 927 1004 VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3) 928 1005 { 929 int rc = pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, false /*fTryAgain*/); 930 if ( rc == VINF_SUCCESS 931 && fCallRing3 932 && pThis->s.Core.pValidatorWrite 933 && pThis->s.Core.pValidatorWrite->hThread != NIL_RTTHREAD) 934 RTLockValidatorRecExclReleaseOwnerUnchecked(pThis->s.Core.pValidatorWrite); 935 return rc; 1006 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, false /*fTryAgain*/, fCallRing3 /*fNoVal*/); 936 1007 } 937 1008 #endif /* IN_RING3 */ … … 945 1016 * during the operation. 946 1017 * @param pThis Pointer to the read/write critical section. 1018 * @param fNoVal No validation records (i.e. queued release). 947 1019 * @sa PDMCritSectRwLeaveShared, RTCritSectRwLeaveExcl. 948 1020 */ 949 VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pThis)1021 static int pdmCritSectRwLeaveExclWorker(PPDMCRITSECTRW pThis, bool fNoVal) 950 1022 { 951 1023 /* … … 967 1039 AssertReturn(pThis->s.Core.cWriterReads == 0, VERR_WRONG_ORDER); /* (must release all read recursions before the final write.) */ 968 1040 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 969 int rc9 = RTLockValidatorRecExclReleaseOwner(pThis->s.Core.pValidatorWrite, true); 970 if (RT_FAILURE(rc9)) 971 return rc9; 1041 if (fNoVal) 1042 Assert(pThis->s.Core.pValidatorWrite->hThread == NIL_RTTHREAD); 1043 else 1044 { 1045 int rc9 = RTLockValidatorRecExclReleaseOwner(pThis->s.Core.pValidatorWrite, true); 1046 if (RT_FAILURE(rc9)) 1047 return rc9; 1048 } 972 1049 #endif 973 1050 /* … … 1047 1124 Assert(pThis->s.Core.cWriteRecursions != 0); 1048 1125 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 1049 int rc9 = RTLockValidatorRecExclUnwind(pThis->s.Core.pValidatorWrite); 1050 if (RT_FAILURE(rc9)) 1051 return rc9; 1126 if (fNoVal) 1127 Assert(pThis->s.Core.pValidatorWrite->hThread == NIL_RTTHREAD); 1128 else 1129 { 1130 int rc9 = RTLockValidatorRecExclUnwind(pThis->s.Core.pValidatorWrite); 1131 if (RT_FAILURE(rc9)) 1132 return rc9; 1133 } 1052 1134 #endif 1053 1135 ASMAtomicDecU32(&pThis->s.Core.cWriteRecursions); … … 1056 1138 return VINF_SUCCESS; 1057 1139 } 1140 1141 1142 /** 1143 * Leave a critical section held exclusively. 1144 * 1145 * @returns VBox status code. 1146 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 1147 * during the operation. 1148 * @param pThis Pointer to the read/write critical section. 1149 * @sa PDMCritSectRwLeaveShared, RTCritSectRwLeaveExcl. 1150 */ 1151 VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pThis) 1152 { 1153 return pdmCritSectRwLeaveExclWorker(pThis, false /*fNoVal*/); 1154 } 1155 1156 1157 #if defined(IN_RING3) || defined(IN_RING0) 1158 /** 1159 * PDMCritSectBothFF interface. 1160 * 1161 * @param pThis Pointer to the read/write critical section. 1162 */ 1163 void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis) 1164 { 1165 pdmCritSectRwLeaveExclWorker(pThis, true /*fNoVal*/); 1166 } 1167 #endif 1058 1168 1059 1169 -
trunk/src/VBox/VMM/include/PDMInternal.h
r45152 r45299 1331 1331 void pdmUnlock(PVM pVM); 1332 1332 1333 #if defined(IN_RING3) || defined(IN_RING0) 1334 void pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis); 1335 void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis); 1336 #endif 1337 1333 1338 /** @} */ 1334 1339
Note:
See TracChangeset
for help on using the changeset viewer.