- Timestamp:
- Apr 2, 2013 6:42:50 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 84691
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r45276 r45293 421 421 VMMAll/PDMAll.cpp \ 422 422 VMMAll/PDMAllCritSect.cpp \ 423 VMMAll/PDMAllCritSectRw.cpp \ 423 424 VMMAll/PDMAllCritSectBoth.cpp \ 424 425 VMMAll/PDMAllQueue.cpp \ … … 529 530 VMMAll/PDMAll.cpp \ 530 531 VMMAll/PDMAllCritSect.cpp \ 532 VMMAll/PDMAllCritSectRw.cpp \ 531 533 VMMAll/PDMAllCritSectBoth.cpp \ 532 534 VMMAll/PDMAllQueue.cpp \ -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r45189 r45293 207 207 return VERR_SEM_BUSY; 208 208 209 /* Add ourselves to the queue and wait for the direction to change. */ 209 #if defined(IN_RING3) 210 /* 211 * Add ourselves to the queue and wait for the direction to change. 212 */ 210 213 uint64_t c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; 211 214 c++; … … 225 228 { 226 229 int rc; 227 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)230 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 228 231 rc = RTLockValidatorRecSharedCheckBlocking(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos, true, 229 232 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_READ, false); 230 233 if (RT_SUCCESS(rc)) 231 # else234 # else 232 235 RTTHREAD hThreadSelf = RTThreadSelf(); 233 236 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ, false); 234 # endif237 # endif 235 238 { 236 239 do … … 295 298 } 296 299 297 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)300 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 298 301 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 299 # endif302 # endif 300 303 break; 301 304 } 305 306 #else 307 /* 308 * We cannot call SUPSemEventMultiWaitNoResume in this context. Go 309 * back to ring-3 and do it there or return rcBusy. 310 */ 311 if (rcBusy == VINF_SUCCESS) 312 { 313 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 314 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 315 /** @todo Should actually do this in via VMMR0.cpp instead of going all the way 316 * back to ring-3. Goes for both kind of crit sects. */ 317 return VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_SHARED, MMHyperCCToR3(pVM, pThis)); 318 } 319 return rcBusy; 320 #endif 302 321 } 303 322 … … 342 361 VMMDECL(int) PDMCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy) 343 362 { 344 #if defined(PDMCRITSECTRW_STRICT) &&defined(IN_RING3)363 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 345 364 return pdmCritSectRwEnterShared(pThis, rcBusy, NULL, false /*fTryOnly*/); 346 365 #else … … 375 394 VMMDECL(int) PDMCritSectRwEnterSharedDebug(PPDMCRITSECTRW pThis, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL) 376 395 { 396 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 397 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, false /*fTryOnly*/); 398 #else 377 399 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 378 400 return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/); 401 #endif 379 402 } 380 403 … … 401 424 VMMDECL(int) PDMCritSectRwTryEnterShared(PPDMCRITSECTRW pThis) 402 425 { 403 #if defined(PDMCRITSECTRW_STRICT) &&defined(IN_RING3)426 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 404 427 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, true /*fTryOnly*/); 405 428 #else … … 431 454 VMMDECL(int) PDMCritSectRwTryEnterSharedDebug(PPDMCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 432 455 { 456 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 457 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, true /*fTryOnly*/); 458 #else 433 459 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 434 460 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryOnly*/); 435 } 461 #endif 462 } 463 464 465 #ifdef IN_RING3 466 /** 467 * Enters a PDM read/write critical section with shared (read) access. 468 * 469 * @returns VINF_SUCCESS if entered successfully. 470 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 471 * during the operation. 472 * 473 * @param pThis Pointer to the read/write critical section. 474 * @param fCallRing3 Whether this is a VMMRZCallRing3()request. 475 */ 476 VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3) 477 { 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 */ 436 492 437 493 … … 484 540 else 485 541 { 486 /* Reverse the direction and signal the reader threads. */ 542 #if defined(IN_RING3) 543 /* Reverse the direction and signal the writer threads. */ 487 544 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_DIR_MASK); 488 545 u64State |= RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT; … … 493 550 break; 494 551 } 552 #else 553 /* Queue the exit request (ring-3). */ 554 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 555 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 556 uint32_t i = pVCpu->pdm.s.cQueuedCritSectRwShrdLeaves++; 557 LogFlow(("PDMCritSectRwLeaveShared: [%d]=%p => R3\n", i, pThis)); 558 AssertFatal(i < RT_ELEMENTS(pVCpu->pdm.s.apQueuedCritSectRwShrdLeaves)); 559 pVCpu->pdm.s.apQueuedCritSectRwShrdLeaves[i] = MMHyperCCToR3(pVM, pThis); 560 VMCPU_FF_SET(pVCpu, VMCPU_FF_PDM_CRITSECT); 561 VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); 562 STAM_REL_COUNTER_INC(&pVM->pdm.s.StatQueuedCritSectLeaves); 563 STAM_REL_COUNTER_INC(&pThis->s.StatContentionRZLeaveShared); 564 #endif 495 565 } 496 566 … … 614 684 */ 615 685 bool fDone = (u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT) 686 #if defined(IN_RING3) 616 687 && ( ((u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT) == 1 617 || fTryOnly); 688 || fTryOnly) 689 #endif 690 ; 618 691 if (fDone) 619 692 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 620 693 if (!fDone) 621 694 { 695 #if defined(IN_RING3) 622 696 /* 623 697 * Wait for our turn. … … 626 700 { 627 701 int rc; 628 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)702 # if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 629 703 if (!fTryOnly) 630 704 { … … 637 711 rc = VINF_SUCCESS; 638 712 if (RT_SUCCESS(rc)) 639 # else713 # else 640 714 RTTHREAD hThreadSelf = RTThreadSelf(); 641 715 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false); 642 # endif716 # endif 643 717 { 644 718 do … … 676 750 AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */ 677 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 678 778 } 679 779 … … 715 815 VMMDECL(int) PDMCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy) 716 816 { 717 #if defined(PDMCRITSECTRW_STRICT) &&defined(IN_RING3)817 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 718 818 return pdmCritSectRwEnterExcl(pThis, rcBusy, NULL, false /*fTryAgain*/); 719 819 #else … … 749 849 VMMDECL(int) PDMCritSectRwEnterExclDebug(PPDMCRITSECTRW pThis, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL) 750 850 { 851 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 852 return pdmCritSectRwEnterExcl(pThis, rcBusy, NULL, false /*fTryAgain*/); 853 #else 751 854 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 752 855 return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/); 856 #endif 753 857 } 754 858 … … 771 875 VMMDECL(int) PDMCritSectRwTryEnterExcl(PPDMCRITSECTRW pThis) 772 876 { 773 #if defined(PDMCRITSECTRW_STRICT) &&defined(IN_RING3)877 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 774 878 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, true /*fTryAgain*/); 775 879 #else … … 801 905 VMMDECL(int) PDMCritSectRwTryEnterExclDebug(PPDMCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 802 906 { 907 #if !defined(PDMCRITSECTRW_STRICT) || !defined(IN_RING3) 908 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, true /*fTryAgain*/); 909 #else 803 910 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 804 911 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryAgain*/); 805 } 912 #endif 913 } 914 915 916 #ifdef IN_RING3 917 /** 918 * Enters a PDM read/write critical section with exclusive (write) access. 919 * 920 * @returns VINF_SUCCESS if entered successfully. 921 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 922 * during the operation. 923 * 924 * @param pThis Pointer to the read/write critical section. 925 * @param fCallRing3 Whether this is a VMMRZCallRing3()request. 926 */ 927 VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3) 928 { 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; 936 } 937 #endif /* IN_RING3 */ 806 938 807 939 … … 842 974 * Update the state. 843 975 */ 976 #if defined(IN_RING3) 844 977 ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0); 978 STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl); 845 979 ASMAtomicWriteHandle(&pThis->s.Core.hNativeWriter, NIL_RTNATIVETHREAD); 846 STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);847 980 848 981 for (;;) … … 890 1023 return VERR_SEM_DESTROYED; 891 1024 } 1025 #else 1026 /* 1027 * We cannot call neither SUPSemEventSignal nor SUPSemEventMultiSignal, 1028 * so queue the exit request (ring-3). 1029 */ 1030 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 1031 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 1032 uint32_t i = pVCpu->pdm.s.cQueuedCritSectRwExclLeaves++; 1033 LogFlow(("PDMCritSectRwLeaveShared: [%d]=%p => R3\n", i, pThis)); 1034 AssertFatal(i < RT_ELEMENTS(pVCpu->pdm.s.apQueuedCritSectLeaves)); 1035 pVCpu->pdm.s.apQueuedCritSectRwExclLeaves[i] = MMHyperCCToR3(pVM, pThis); 1036 VMCPU_FF_SET(pVCpu, VMCPU_FF_PDM_CRITSECT); 1037 VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); 1038 STAM_REL_COUNTER_INC(&pVM->pdm.s.StatQueuedCritSectLeaves); 1039 STAM_REL_COUNTER_INC(&pThis->s.StatContentionRZLeaveExcl); 1040 #endif 892 1041 } 893 1042 else -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r45276 r45293 81 81 #include <VBox/vmm/pdmqueue.h> 82 82 #include <VBox/vmm/pdmcritsect.h> 83 #include <VBox/vmm/pdmcritsectrw.h> 83 84 #include <VBox/vmm/pdmapi.h> 84 85 #include <VBox/vmm/cpum.h> … … 2116 2117 2117 2118 /* 2119 * Enter a r/w critical section exclusively. 2120 */ 2121 case VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL: 2122 { 2123 pVCpu->vmm.s.rcCallRing3 = PDMR3CritSectRwEnterExclEx((PPDMCRITSECTRW)(uintptr_t)pVCpu->vmm.s.u64CallRing3Arg, 2124 true /*fCallRing3*/); 2125 break; 2126 } 2127 2128 /* 2129 * Enter a r/w critical section shared. 2130 */ 2131 case VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_SHARED: 2132 { 2133 pVCpu->vmm.s.rcCallRing3 = PDMR3CritSectRwEnterSharedEx((PPDMCRITSECTRW)(uintptr_t)pVCpu->vmm.s.u64CallRing3Arg, 2134 true /*fCallRing3*/); 2135 break; 2136 } 2137 2138 /* 2118 2139 * Acquire the PDM lock. 2119 2140 */
Note:
See TracChangeset
for help on using the changeset viewer.