VirtualBox

Changeset 90660 in vbox


Ignore:
Timestamp:
Aug 12, 2021 12:27:29 PM (3 years ago)
Author:
vboxsync
Message:

VMM/PDMCritSectRwLeaveExcl: Code deduplication. bugref:6695

File:
1 edited

Legend:

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

    r90659 r90660  
    14581458#endif
    14591459
    1460 #if defined(IN_RING3)
     1460#if defined(IN_RING3) || defined(IN_RING0)
    14611461    /*
    14621462     * Ring-3: Straight forward, just update the state and if necessary signal waiters.
    1463      */
    1464 # ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
    1465     pThis->s.Core.cWriteRecursions = 0;
    1466 # else
    1467     ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0);
    1468 # endif
    1469     STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);
    1470     ASMAtomicWriteHandle(&pThis->s.Core.u.s.hNativeWriter, NIL_RTNATIVETHREAD);
    1471 
    1472     for (;;)
    1473     {
    1474         uint64_t u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    1475         uint64_t u64OldState = u64State;
    1476 
    1477         uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT;
    1478         AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid write count on leave"));
    1479         c--;
    1480 
    1481         if (   c > 0
    1482             || (u64State & RTCSRW_CNT_RD_MASK) == 0)
    1483         {
    1484             /* Don't change the direction, wake up the next writer if any. */
    1485             u64State &= ~RTCSRW_CNT_WR_MASK;
    1486             u64State |= c << RTCSRW_CNT_WR_SHIFT;
    1487             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    1488             {
    1489                 if (c > 0)
    1490                 {
    1491                     int rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite);
    1492                     AssertRC(rc);
    1493                 }
    1494                 return VINF_SUCCESS;
    1495             }
    1496         }
    1497         else
    1498         {
    1499             /* Reverse the direction and signal the reader threads. */
    1500             u64State &= ~(RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    1501             u64State |= RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT;
    1502             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    1503             {
    1504                 Assert(!pThis->s.Core.fNeedReset);
    1505                 ASMAtomicWriteBool(&pThis->s.Core.fNeedReset, true);
    1506                 int rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead);
    1507                 AssertRC(rc);
    1508                 return VINF_SUCCESS;
    1509             }
    1510         }
    1511 
    1512         ASMNopPause();
    1513         if (pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC)
    1514         { /*likely*/ }
    1515         else
    1516             return VERR_SEM_DESTROYED;
    1517         ASMNopPause();
    1518     }
    1519 
    1520 
    1521 #elif defined(IN_RING0)
    1522     /*
    15231463     * Ring-0: Try leave for real, depends on host and context.
    15241464     */
     1465# ifdef IN_RING0
    15251466    Assert(RTSemEventIsSignalSafe() == RTSemEventMultiIsSignalSafe());
    15261467    PVMCPUCC pVCpu = VMMGetCpu(pVM);
     
    15321473            && ASMIntAreEnabled())                      /* ... and interrupts hasn't yet been disabled. Special pre-GC HM env. */
    15331474       )
     1475# endif
    15341476    {
    15351477# ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     
    15631505                    if (c == 0)
    15641506                        rc = VINF_SUCCESS;
    1565                     else if (RTSemEventIsSignalSafe() || pVCpu == NULL)
    1566                         rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite);
    1567                     else
     1507# ifdef IN_RING0
     1508                    else if (!RTSemEventIsSignalSafe() && pVCpu != NULL)
    15681509                    {
    15691510                        VMMR0EMTBLOCKCTX Ctx;
     
    15751516                        VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
    15761517                    }
     1518# endif
     1519                    else
     1520                        rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite);
    15771521                    AssertRC(rc);
    15781522                    return rc;
     
    15921536
    15931537                    int rc;
    1594                     if (RTSemEventMultiIsSignalSafe() || pVCpu == NULL)
    1595                         rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead);
    1596                     else
     1538# ifdef IN_RING0
     1539                    if (!RTSemEventMultiIsSignalSafe() && pVCpu != NULL)
    15971540                    {
    15981541                        VMMR0EMTBLOCKCTX Ctx;
     
    16041547                        VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
    16051548                    }
     1549                    else
     1550# endif
     1551                        rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead);
    16061552                    AssertRC(rc);
    16071553                    return rc;
     
    16181564        /* not reached! */
    16191565    }
    1620 #endif /* IN_RING0 */
     1566#endif /* IN_RING3 || IN_RING0 */
    16211567
    16221568#ifndef IN_RING3
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