VirtualBox

Changeset 90650 in vbox


Ignore:
Timestamp:
Aug 12, 2021 10:18:48 AM (3 years ago)
Author:
vboxsync
Message:

VMM/PDMCritSectRwLeaveExcl: Used ASMAtomicCmpWriteU128U to optimize leaving when there is no contention. Without it, the leave is always queued for ring-3. bugref:6695

File:
1 edited

Legend:

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

    r90637 r90650  
    4343# include <iprt/time.h>
    4444#endif
     45#ifdef RT_ARCH_AMD64
     46# include <iprt/x86.h>
     47#endif
    4548
    4649
     
    7174#undef PDMCritSectRwTryEnterShared
    7275
     76
     77/*********************************************************************************************************************************
     78*   Defined Constants And Macros                                                                                                 *
     79*********************************************************************************************************************************/
     80#if defined(RTASM_HAVE_CMP_WRITE_U128) && defined(RT_ARCH_AMD64)
     81static int32_t g_fCmpWriteSupported = -1;
     82#endif
     83
     84
     85#ifdef RTASM_HAVE_CMP_WRITE_U128
     86
     87# ifdef RT_ARCH_AMD64
     88/**
     89 * Called once to initialize g_fCmpWriteSupported.
     90 */
     91DECL_NO_INLINE(static, bool) pdmCritSectRwIsCmpWriteU128SupportedSlow(void)
     92{
     93    bool const fCmpWriteSupported = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16);
     94    ASMAtomicWriteS32(&g_fCmpWriteSupported, fCmpWriteSupported);
     95    return fCmpWriteSupported;
     96}
     97# endif
     98
     99
     100/**
     101 * Indicates whether hardware actually supports 128-bit compare & write.
     102 */
     103DECL_FORCE_INLINE(bool) pdmCritSectRwIsCmpWriteU128Supported(void)
     104{
     105# ifdef RT_ARCH_AMD64
     106    int32_t const fCmpWriteSupported = g_fCmpWriteSupported;
     107    if (RT_LIKELY(fCmpWriteSupported >= 0))
     108        return fCmpWriteSupported != 0;
     109    return pdmCritSectRwIsCmpWriteU128SupportedSlow();
     110# else
     111    return true;
     112# endif
     113}
     114
     115#endif /* RTASM_HAVE_CMP_WRITE_U128 */
    73116
    74117/**
     
    13451388        }
    13461389#endif
     1390
     1391#ifdef RTASM_HAVE_CMP_WRITE_U128
     1392        /*
     1393         * See if we can get out w/o any signalling as this is a common case.
     1394         */
     1395        if (pdmCritSectRwIsCmpWriteU128Supported())
     1396        {
     1397            RTCRITSECTRWSTATE OldState;
     1398            OldState.s.u64State = ASMAtomicUoReadU64(&pThis->s.Core.u.s.u64State);
     1399            if (OldState.s.u64State == ((UINT64_C(1) << RTCSRW_CNT_WR_SHIFT) | (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)))
     1400            {
     1401                OldState.s.hNativeWriter = hNativeSelf;
     1402                AssertCompile(sizeof(OldState.s.hNativeWriter) == sizeof(OldState.u128.s.Lo));
     1403
     1404                RTCRITSECTRWSTATE NewState;
     1405                NewState.s.u64State      = RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT;
     1406                NewState.s.hNativeWriter = NIL_RTNATIVETHREAD;
     1407
     1408                pThis->s.Core.cWriteRecursions = 0;
     1409                STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);
     1410
     1411                if (ASMAtomicCmpWriteU128U(&pThis->s.Core.u.u128, NewState.u128, OldState.u128))
     1412                    return VINF_SUCCESS;
     1413
     1414                /* bail out. */
     1415                pThis->s.Core.cWriteRecursions = 1;
     1416            }
     1417        }
     1418#endif
     1419
    13471420        /*
    13481421         * Update the state.
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