VirtualBox

Changeset 90610 in vbox


Ignore:
Timestamp:
Aug 10, 2021 9:56:02 PM (3 years ago)
Author:
vboxsync
Message:

VMM/PDMCritSecRw: More code refactoring. bugref:6695

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp

    r90608 r90610  
    737737 *
    738738 * @returns @a rc unless corrupted.
    739  * @param   pVM         The cross context VM structure.
     739 * @param   pThis       Pointer to the read/write critical section.
    740740 * @param   rc          The status to return.
    741741 */
     
    763763}
    764764
     765#if defined(IN_RING3) || defined(IN_RING0)
     766/**
     767 * Worker for pdmCritSectRwEnterExcl that handles waiting when the section is
     768 * contended.
     769 */
     770static 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
    765831
    766832/**
     
    910976           )
    911977        {
    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);
    929986# 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;
    963991        }
    964992        else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette