Changeset 90610 in vbox
- Timestamp:
- Aug 10, 2021 9:56:02 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r90608 r90610 737 737 * 738 738 * @returns @a rc unless corrupted. 739 * @param p VM The cross context VM structure.739 * @param pThis Pointer to the read/write critical section. 740 740 * @param rc The status to return. 741 741 */ … … 763 763 } 764 764 765 #if defined(IN_RING3) || defined(IN_RING0) 766 /** 767 * Worker for pdmCritSectRwEnterExcl that handles waiting when the section is 768 * contended. 769 */ 770 static int pdmR3R0CritSectRwEnterExclContended(PVMCC pVM, PVMCPUCC pVCpu, PPDMCRITSECTRW pThis, RTNATIVETHREAD hNativeSelf, 771 PCRTLOCKVALSRCPOS pSrcPos, int rcBusy, RTTHREAD hThreadSelf) 772 { 773 RT_NOREF(hThreadSelf, rcBusy, pSrcPos, pVCpu); 774 775 for (uint32_t iLoop = 0; ; iLoop++) 776 { 777 /* 778 * Wait for our turn. 779 */ 780 int rc; 781 # ifdef IN_RING3 782 # ifdef PDMCRITSECTRW_STRICT 783 rc = RTLockValidatorRecExclCheckBlocking(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true, 784 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_WRITE, false); 785 if (RT_SUCCESS(rc)) 786 # else 787 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false); 788 # endif 789 # endif 790 { 791 for (;;) 792 { 793 rc = SUPSemEventWaitNoResume(pVM->pSession, 794 (SUPSEMEVENT)pThis->s.Core.hEvtWrite, 795 RT_INDEFINITE_WAIT); 796 if ( rc != VERR_INTERRUPTED 797 || pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 798 break; 799 # ifdef IN_RING0 800 pdmR0CritSectRwYieldToRing3(pVM); 801 # endif 802 } 803 804 # ifdef IN_RING3 805 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 806 # endif 807 if (pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC) 808 { /* likely */ } 809 else 810 return VERR_SEM_DESTROYED; 811 } 812 if (RT_FAILURE(rc)) 813 return pdmCritSectRwEnterExclBailOut(pThis, rc); 814 815 /* 816 * Try take exclusive write ownership. 817 */ 818 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 819 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 820 { 821 bool fDone; 822 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 823 if (fDone) 824 return VINF_SUCCESS; 825 } 826 AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */ 827 } 828 } 829 #endif /* IN_RING3 || IN_RING0 */ 830 765 831 766 832 /** … … 910 976 ) 911 977 { 912 /* 913 * Wait for our turn. 914 */ 915 for (uint32_t iLoop = 0; ; iLoop++) 916 { 917 int rc; 918 # ifdef IN_RING3 919 # ifdef PDMCRITSECTRW_STRICT 920 if (hThreadSelf == NIL_RTTHREAD) 921 hThreadSelf = RTThreadSelfAutoAdopt(); 922 rc = RTLockValidatorRecExclCheckBlocking(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true, 923 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_WRITE, false); 924 if (RT_SUCCESS(rc)) 925 # else 926 RTTHREAD hThreadSelf = RTThreadSelf(); 927 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false); 928 # endif 978 # if defined(IN_RING3) && defined(PDMCRITSECTRW_STRICT) 979 if (hThreadSelf == NIL_RTTHREAD) 980 hThreadSelf = RTThreadSelfAutoAdopt(); 981 int rc = pdmR3R0CritSectRwEnterExclContended(pVM, NULL, pThis, hNativeSelf, pSrcPos, rcBusy, hThreadSelf); 982 # elif defined(IN_RING3) 983 int rc = pdmR3R0CritSectRwEnterExclContended(pVM, NULL, pThis, hNativeSelf, pSrcPos, rcBusy, RTThreadSelf()); 984 # else 985 int rc = pdmR3R0CritSectRwEnterExclContended(pVM, NULL, pThis, hNativeSelf, pSrcPos, rcBusy, NIL_RTTHREAD); 929 986 # endif 930 { 931 for (;;) 932 { 933 rc = SUPSemEventWaitNoResume(pVM->pSession, 934 (SUPSEMEVENT)pThis->s.Core.hEvtWrite, 935 RT_INDEFINITE_WAIT); 936 if ( rc != VERR_INTERRUPTED 937 || pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 938 break; 939 # ifdef IN_RING0 940 pdmR0CritSectRwYieldToRing3(pVM); 941 # endif 942 } 943 # ifdef IN_RING3 944 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 945 # endif 946 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 947 return VERR_SEM_DESTROYED; 948 } 949 if (RT_FAILURE(rc)) 950 return pdmCritSectRwEnterExclBailOut(pThis, rc); 951 952 /* Try take exclusive write ownership. */ 953 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 954 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 955 { 956 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 957 if (fDone) 958 break; 959 } 960 AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */ 961 } 962 987 if (RT_SUCCESS(rc)) 988 { /*likely*/ } 989 else 990 return rc; 963 991 } 964 992 else
Note:
See TracChangeset
for help on using the changeset viewer.