VirtualBox

Changeset 45299 in vbox for trunk/src


Ignore:
Timestamp:
Apr 3, 2013 9:47:49 AM (12 years ago)
Author:
vboxsync
Message:

PDMCritSectRw: Fixes.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

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

    r45152 r45299  
    4545           || pVCpu->pdm.s.cQueuedCritSectRwExclLeaves > 0);
    4646
    47 #if 0 /* Later... */
    4847    /* Shared leaves. */
    4948    i = pVCpu->pdm.s.cQueuedCritSectRwShrdLeaves;
     
    5857# endif
    5958
    60         PDMCritSectRwLeaveShared(pCritSectRw);
     59        pdmCritSectRwLeaveSharedQueued(pCritSectRw);
    6160        LogFlow(("PDMR3CritSectFF: %p (R/W)\n", pCritSectRw));
    6261    }
     
    7473# endif
    7574
    76         PDMCritSectRwLeaveExcl(pCritSectRw);
     75        pdmCritSectRwLeaveExclQueued(pCritSectRw);
    7776        LogFlow(("PDMR3CritSectFF: %p (R/W)\n", pCritSectRw));
    7877    }
    79 #endif
    8078
    8179    /* Normal leaves. */
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp

    r45293 r45299  
    8080    RTNATIVETHREAD  hNativeSelf = RTThreadNativeSelf();
    8181#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),
    8383                    NIL_RTNATIVETHREAD);
    8484    PVM             pVM         = pThis->s.CTX_SUFF(pVM);   AssertPtr(pVM);
     
    123123
    124124
    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 */
     135static int pdmCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly, PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
    126136{
    127137    /*
     
    166176            {
    167177#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);
    169180#endif
    170181                break;
     
    180191                Assert(!pThis->s.Core.fNeedReset);
    181192#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);
    183195#endif
    184196                break;
     
    194206            {
    195207#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                }
    199214#endif
    200215                Assert(pThis->s.Core.cWriterReads < UINT32_MAX / 2);
    201216                ASMAtomicIncU32(&pThis->s.Core.cWriterReads);
     217                STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterShared));
    202218                return VINF_SUCCESS; /* don't break! */
    203219            }
    204220
    205             /* If we're only trying, return already. */
     221            /*
     222             * If we're only trying, return already.
     223             */
    206224            if (fTryOnly)
     225            {
     226                STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterShared));
    207227                return VERR_SEM_BUSY;
     228            }
    208229
    209230#if defined(IN_RING3)
     
    299320
    300321# 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);
    302324# endif
    303325                break;
     
    309331             * back to ring-3 and do it there or return rcBusy.
    310332             */
     333            STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterShared));
    311334            if (rcBusy == VINF_SUCCESS)
    312335            {
     
    362385{
    363386#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*/);
    365388#else
    366389    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
    367     return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/);
     390    return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, &SrcPos, false /*fNoVal*/);
    368391#endif
    369392}
     
    395418{
    396419#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*/);
    398421#else
    399422    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
    400     return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/);
     423    return pdmCritSectRwEnterShared(pThis, rcBusy, false /*fTryOnly*/, &SrcPos, false /*fNoVal*/);
    401424#endif
    402425}
     
    425448{
    426449#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*/);
    428451#else
    429452    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*/);
    431454#endif
    432455}
     
    455478{
    456479#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*/);
    458481#else
    459482    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*/);
    461484#endif
    462485}
     
    476499VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3)
    477500{
    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
    492504
    493505
     
    498510 * @retval  VERR_SEM_DESTROYED if the critical section is delete before or
    499511 *          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).
    501514 * @sa      PDMCritSectRwEnterShared, PDMCritSectRwTryEnterShared,
    502515 *          PDMCritSectRwEnterSharedDebug, PDMCritSectRwTryEnterSharedDebug,
    503516 *          PDMCritSectRwLeaveExcl, RTCritSectRwLeaveShared.
    504517 */
    505 VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pThis)
     518static int pdmCritSectRwLeaveSharedWorker(PPDMCRITSECTRW pThis, bool fNoVal)
    506519{
    507520    /*
     
    519532    {
    520533#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        }
    524542#endif
    525543        for (;;)
     
    578596        AssertReturn(pThis->s.Core.cWriterReads > 0, VERR_NOT_OWNER);
    579597#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        }
    583604#endif
    584605        ASMAtomicDecU32(&pThis->s.Core.cWriterReads);
     
    588609}
    589610
    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 */
     622VMMDECL(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 */
     634void 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 */
     651static int pdmCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly, PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
    592652{
    593653    /*
     
    618678        Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    619679#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        }
    623686#endif
    624687        Assert(pThis->s.Core.cWriteRecursions < UINT32_MAX / 2);
     
    657720        }
    658721        else if (fTryOnly)
     722        {
    659723            /* Wrong direction and we're not supposed to wait, just return. */
     724            STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterExcl));
    660725            return VERR_SEM_BUSY;
     726        }
    661727        else
    662728        {
     
    693759    if (!fDone)
    694760    {
     761        STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,EnterExcl));
     762
    695763#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;
    702772# if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)
    703             if (!fTryOnly)
    704             {
    705773                if (hThreadSelf == NIL_RTTHREAD)
    706774                    hThreadSelf = RTThreadSelfAutoAdopt();
    707775                rc = RTLockValidatorRecExclCheckBlocking(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true,
    708776                                                         RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_WRITE, false);
    709             }
    710             else
    711                 rc = VINF_SUCCESS;
    712             if (RT_SUCCESS(rc))
     777                if (RT_SUCCESS(rc))
    713778# else
    714             RTTHREAD hThreadSelf = RTThreadSelf();
    715             RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false);
     779                RTTHREAD hThreadSelf = RTThreadSelf();
     780                RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false);
    716781# endif
    717             {
    718                 do
    719                     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 (;;)
    731782                {
    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)
    738813                        break;
    739814                }
    740                 return rc;
     815                AssertMsg(iLoop < 1000, ("%u\n", iLoop)); /* may loop a few times here... */
    741816            }
    742817
    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 (;;)
    745830            {
    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))
    748837                    break;
    749838            }
    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        }
    778854    }
    779855
     
    785861    Assert(pThis->s.Core.cWriterReads == 0);
    786862#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);
    788865#endif
    789866    STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterExcl));
     
    816893{
    817894#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*/);
    819896#else
    820897    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
    821     return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/);
     898    return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, &SrcPos, false /*fNoVal*/);
    822899#endif
    823900}
     
    850927{
    851928#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*/);
    853930#else
    854931    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
    855     return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/);
     932    return pdmCritSectRwEnterExcl(pThis, rcBusy, false /*fTryAgain*/, &SrcPos, false /*fNoVal*/);
    856933#endif
    857934}
     
    876953{
    877954#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*/);
    879956#else
    880957    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*/);
    882959#endif
    883960}
     
    906983{
    907984#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*/);
    909986#else
    910987    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*/);
    912989#endif
    913990}
     
    9271004VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3)
    9281005{
    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*/);
    9361007}
    9371008#endif /* IN_RING3 */
     
    9451016 *          during the operation.
    9461017 * @param   pThis       Pointer to the read/write critical section.
     1018 * @param   fNoVal      No validation records (i.e. queued release).
    9471019 * @sa      PDMCritSectRwLeaveShared, RTCritSectRwLeaveExcl.
    9481020 */
    949 VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pThis)
     1021static int pdmCritSectRwLeaveExclWorker(PPDMCRITSECTRW pThis, bool fNoVal)
    9501022{
    9511023    /*
     
    9671039        AssertReturn(pThis->s.Core.cWriterReads == 0, VERR_WRONG_ORDER); /* (must release all read recursions before the final write.) */
    9681040#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        }
    9721049#endif
    9731050        /*
     
    10471124        Assert(pThis->s.Core.cWriteRecursions != 0);
    10481125#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        }
    10521134#endif
    10531135        ASMAtomicDecU32(&pThis->s.Core.cWriteRecursions);
     
    10561138    return VINF_SUCCESS;
    10571139}
     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 */
     1151VMMDECL(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 */
     1163void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis)
     1164{
     1165    pdmCritSectRwLeaveExclWorker(pThis, true /*fNoVal*/);
     1166}
     1167#endif
    10581168
    10591169
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r45152 r45299  
    13311331void        pdmUnlock(PVM pVM);
    13321332
     1333#if defined(IN_RING3) || defined(IN_RING0)
     1334void        pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis);
     1335void        pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis);
     1336#endif
     1337
    13331338/** @} */
    13341339
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