VirtualBox

Changeset 90654 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Aug 12, 2021 10:48:51 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
146266
Message:

VMM/PDMCritSectRwLeaveExcl: Relax use of atomics. bugref:6695

File:
1 edited

Legend:

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

    r90650 r90654  
    6767/** Max number of write or write/read recursions. */
    6868#define PDM_CRITSECTRW_MAX_RECURSIONS           _1M
     69
     70/** Skips some of the overly paranoid atomic reads and updates.
     71 * Makes some assumptions about cache coherence, though not brave enough not to
     72 * always end with an atomic update. */
     73#define PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     74
     75/** For reading RTCRITSECTRWSTATE::s::u64State. */
     76#ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     77# define PDMCRITSECTRW_READ_STATE(a_pu64State)  ASMAtomicUoReadU64(a_pu64State)
     78#else
     79# define PDMCRITSECTRW_READ_STATE(a_pu64State)  ASMAtomicReadU64(a_pu64State)
     80#endif
     81
    6982
    7083/* Undefine the automatic VBOX_STRICT API mappings. */
     
    242255     * Get cracking...
    243256     */
    244     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     257    uint64_t u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    245258    uint64_t u64OldState = u64State;
    246259
     
    378391                            for (;;)
    379392                            {
    380                                 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     393                                u64OldState = u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    381394                                c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT;
    382395                                AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid read count on bailout"));
     
    394407
    395408                        Assert(pThis->s.Core.fNeedReset);
    396                         u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     409                        u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    397410                        if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    398411                            break;
     
    423436                            break;
    424437                        }
    425                         u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     438                        u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    426439                    }
    427440
     
    460473
    461474        ASMNopPause();
    462         u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     475        u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    463476        u64OldState = u64State;
    464477    }
     
    466479    /* got it! */
    467480    STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterShared));
    468     Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
     481    Assert((PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
    469482    return VINF_SUCCESS;
    470483
     
    639652     * Check the direction and take action accordingly.
    640653     */
    641     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     654    uint64_t u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    642655    uint64_t u64OldState = u64State;
    643656    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
     
    715728
    716729            ASMNopPause();
    717             u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     730            u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    718731            u64OldState = u64State;
    719732        }
     
    793806    for (;;)
    794807    {
    795         uint64_t       u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     808        uint64_t       u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    796809        uint64_t const u64OldState = u64State;
    797810        uint64_t c                 = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT;
     
    817830{
    818831    RT_NOREF(hThreadSelf, fNoVal, pSrcPos);
    819     Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    820 
    821 #if 1 /** @todo consider generating less noise... */
     832    Assert((PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     833
     834#ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     835    pThis->s.Core.cWriteRecursions = 1;
     836#else
    822837    ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 1);
    823 #else
    824     pThis->s.Core.cWriteRecursions = 1;
    825838#endif
    826839    Assert(pThis->s.Core.cWriterReads == 0);
     
    982995         * Try take exclusive write ownership.
    983996         */
    984         uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     997        uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    985998        if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    986999        {
     
    10361049    if (hNativeSelf == hNativeWriter)
    10371050    {
    1038         Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     1051        Assert((PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    10391052#if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)
    10401053        if (!fNoVal)
     
    10461059#endif
    10471060        STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterExcl));
     1061#ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     1062        uint32_t const cDepth = ++pThis->s.Core.cWriteRecursions;
     1063#else
    10481064        uint32_t const cDepth = ASMAtomicIncU32(&pThis->s.Core.cWriteRecursions);
     1065#endif
    10491066        AssertReturnStmt(cDepth > 1 && cDepth <= PDM_CRITSECTRW_MAX_RECURSIONS,
    10501067                         ASMAtomicDecU32(&pThis->s.Core.cWriteRecursions),
     
    10561073     * Get cracking.
    10571074     */
    1058     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     1075    uint64_t u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    10591076    uint64_t u64OldState = u64State;
    10601077
     
    11091126
    11101127        ASMNopPause();
    1111         u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     1128        u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    11121129        u64OldState = u64State;
    11131130    }
     
    13961413        {
    13971414            RTCRITSECTRWSTATE OldState;
    1398             OldState.s.u64State = ASMAtomicUoReadU64(&pThis->s.Core.u.s.u64State);
     1415            OldState.s.u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    13991416            if (OldState.s.u64State == ((UINT64_C(1) << RTCSRW_CNT_WR_SHIFT) | (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)))
    14001417            {
     
    14061423                NewState.s.hNativeWriter = NIL_RTNATIVETHREAD;
    14071424
     1425# ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
    14081426                pThis->s.Core.cWriteRecursions = 0;
     1427# else
     1428                ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0);
     1429# endif
    14091430                STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);
    14101431
     
    14271448# endif
    14281449        {
     1450# ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     1451            pThis->s.Core.cWriteRecursions = 0;
     1452# else
    14291453            ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0);
     1454# endif
    14301455            STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);
    14311456            ASMAtomicWriteHandle(&pThis->s.Core.u.s.hNativeWriter, NIL_RTNATIVETHREAD);
     
    14331458            for (;;)
    14341459            {
    1435                 uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     1460                uint64_t u64State    = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    14361461                uint64_t u64OldState = u64State;
    14371462
     
    15201545        }
    15211546#endif
     1547#ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF
     1548        uint32_t const cDepth = --pThis->s.Core.cWriteRecursions;
     1549#else
    15221550        uint32_t const cDepth = ASMAtomicDecU32(&pThis->s.Core.cWriteRecursions);
     1551#endif
    15231552        AssertReturn(cDepth != 0 && cDepth < UINT32_MAX, pdmCritSectRwCorrupted(pThis, "Invalid write recursion value on leave"));
    15241553    }
     
    16181647     * Inspect the state.
    16191648     */
    1620     uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     1649    uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    16211650    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    16221651    {
     
    17221751     * Return the requested data.
    17231752     */
    1724     uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
     1753    uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);
    17251754    if ((u64State & RTCSRW_DIR_MASK) != (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    17261755        return 0;
Note: See TracChangeset for help on using the changeset viewer.

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