VirtualBox

Changeset 90637 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 11, 2021 9:15:42 PM (3 years ago)
Author:
vboxsync
Message:

IPRT/RTCritSectRw,VMM/PDMCritSectRw: Rearranged the core members a little so we can use 128-bit cmpxchg-like hardwoare primitives to update both u64State and hNativeWriter at the same time. This may allow for some optimizations for the PDM version of the code. bugref:6695

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/critsectrw-generic.cpp

    r82968 r90637  
    107107    pThis->fFlags           = (uint16_t)(fFlags & ~RTCRITSECT_FLAGS_RING0);
    108108#endif
    109     pThis->u64State         = 0;
    110     pThis->hNativeWriter    = NIL_RTNATIVETHREAD;
     109    pThis->u.u128.s.Hi      = 0;
     110    pThis->u.u128.s.Lo      = 0;
     111    pThis->u.s.hNativeWriter= NIL_RTNATIVETHREAD;
     112    AssertCompile(sizeof(pThis->u.u128) >= sizeof(pThis->u.s));
    111113    pThis->cWriterReads     = 0;
    112114    pThis->cWriteRecursions = 0;
     
    115117    pThis->pValidatorWrite  = NULL;
    116118    pThis->pValidatorRead   = NULL;
    117 #if HC_ARCH_BITS == 32
    118     pThis->HCPtrPadding     = NIL_RTHCPTR;
    119 #endif
    120119
    121120#ifdef RTCRITSECTRW_STRICT
     
    216215        int            rc9;
    217216        RTNATIVETHREAD hNativeWriter;
    218         ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     217        ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    219218        if (hNativeWriter != NIL_RTTHREAD && hNativeWriter == RTThreadNativeSelf())
    220219            rc9 = RTLockValidatorRecExclCheckOrder(pThis->pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);
     
    229228     * Get cracking...
    230229     */
    231     uint64_t u64State    = ASMAtomicReadU64(&pThis->u64State);
     230    uint64_t u64State    = ASMAtomicReadU64(&pThis->u.s.u64State);
    232231    uint64_t u64OldState = u64State;
    233232
     
    242241            u64State &= ~RTCSRW_CNT_RD_MASK;
    243242            u64State |= c << RTCSRW_CNT_RD_SHIFT;
    244             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     243            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    245244            {
    246245#ifdef RTCRITSECTRW_STRICT
     
    255254            u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    256255            u64State |= (UINT64_C(1) << RTCSRW_CNT_RD_SHIFT) | (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT);
    257             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     256            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    258257            {
    259258                Assert(!pThis->fNeedReset);
     
    269268            RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    270269            RTNATIVETHREAD hNativeWriter;
    271             ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     270            ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    272271            if (hNativeSelf == hNativeWriter)
    273272            {
     
    291290            {
    292291                IPRT_CRITSECTRW_SHARED_BUSY(pThis, NULL,
    293                                             (void *)pThis->hNativeWriter,
     292                                            (void *)pThis->u.s.hNativeWriter,
    294293                                            (uint32_t)((u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT),
    295294                                            (uint32_t)((u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT));
     
    310309            u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT);
    311310
    312             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     311            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    313312            {
    314313                IPRT_CRITSECTRW_SHARED_WAITING(pThis, NULL,
    315                                                (void *)pThis->hNativeWriter,
     314                                               (void *)pThis->u.s.hNativeWriter,
    316315                                               (uint32_t)((u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT),
    317316                                               (uint32_t)((u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT));
     
    340339                        for (;;)
    341340                        {
    342                             u64OldState = u64State = ASMAtomicReadU64(&pThis->u64State);
     341                            u64OldState = u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    343342                            c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; Assert(c > 0);
    344343                            c--;
     
    347346                            u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_WAIT_CNT_RD_MASK);
    348347                            u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT);
    349                             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     348                            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    350349                                break;
    351350                        }
     
    354353
    355354                    Assert(pThis->fNeedReset);
    356                     u64State = ASMAtomicReadU64(&pThis->u64State);
     355                    u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    357356                    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    358357                        break;
     
    371370                    u64State |= cWait << RTCSRW_WAIT_CNT_RD_SHIFT;
    372371
    373                     if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     372                    if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    374373                    {
    375374                        if (cWait == 0)
     
    383382                        break;
    384383                    }
    385                     u64State = ASMAtomicReadU64(&pThis->u64State);
     384                    u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    386385                }
    387386
     
    397396
    398397        ASMNopPause();
    399         u64State = ASMAtomicReadU64(&pThis->u64State);
     398        u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    400399        u64OldState = u64State;
    401400    }
    402401
    403402    /* got it! */
    404     Assert((ASMAtomicReadU64(&pThis->u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
     403    Assert((ASMAtomicReadU64(&pThis->u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
    405404    IPRT_CRITSECTRW_SHARED_ENTERED(pThis, NULL,
    406405                                   (uint32_t)((u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT),
     
    467466     * Check the direction and take action accordingly.
    468467     */
    469     uint64_t u64State    = ASMAtomicReadU64(&pThis->u64State);
     468    uint64_t u64State    = ASMAtomicReadU64(&pThis->u.s.u64State);
    470469    uint64_t u64OldState = u64State;
    471470    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
     
    492491                u64State &= ~RTCSRW_CNT_RD_MASK;
    493492                u64State |= c << RTCSRW_CNT_RD_SHIFT;
    494                 if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     493                if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    495494                    break;
    496495            }
     
    500499                u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_DIR_MASK);
    501500                u64State |= RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT;
    502                 if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     501                if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    503502                {
    504503                    int rc = RTSemEventSignal(pThis->hEvtWrite);
     
    509508
    510509            ASMNopPause();
    511             u64State = ASMAtomicReadU64(&pThis->u64State);
     510            u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    512511            u64OldState = u64State;
    513512        }
     
    517516        RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    518517        RTNATIVETHREAD hNativeWriter;
    519         ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     518        ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    520519        AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER);
    521520        AssertReturn(pThis->cWriterReads > 0, VERR_NOT_OWNER);
     
    567566    RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    568567    RTNATIVETHREAD hNativeWriter;
    569     ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     568    ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    570569    if (hNativeSelf == hNativeWriter)
    571570    {
    572         Assert((ASMAtomicReadU64(&pThis->u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     571        Assert((ASMAtomicReadU64(&pThis->u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    573572#ifdef RTCRITSECTRW_STRICT
    574573        int rc9 = RTLockValidatorRecExclRecursion(pThis->pValidatorWrite, pSrcPos);
     
    582581        if (IPRT_CRITSECTRW_EXCL_ENTERED_ENABLED())
    583582        {
    584             uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     583            uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    585584            IPRT_CRITSECTRW_EXCL_ENTERED(pThis, NULL, cNestings + pThis->cWriterReads,
    586585                                         (uint32_t)((u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT),
     
    594593     * Get cracking.
    595594     */
    596     uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     595    uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    597596    uint64_t u64OldState = u64State;
    598597
     
    608607            u64State &= ~RTCSRW_CNT_WR_MASK;
    609608            u64State |= c << RTCSRW_CNT_WR_SHIFT;
    610             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     609            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    611610                break;
    612611        }
     
    616615            u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    617616            u64State |= (UINT64_C(1) << RTCSRW_CNT_WR_SHIFT) | (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT);
    618             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     617            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    619618                break;
    620619        }
     
    630629            u64State &= ~RTCSRW_CNT_WR_MASK;
    631630            u64State |= c << RTCSRW_CNT_WR_SHIFT;
    632             if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     631            if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    633632                break;
    634633        }
     
    638637
    639638        ASMNopPause();
    640         u64State = ASMAtomicReadU64(&pThis->u64State);
     639        u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    641640        u64OldState = u64State;
    642641    }
     
    650649                  || fTryOnly);
    651650    if (fDone)
    652         ASMAtomicCmpXchgHandle(&pThis->hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
     651        ASMAtomicCmpXchgHandle(&pThis->u.s.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
    653652    if (!fDone)
    654653    {
     
    660659            for (;;)
    661660            {
    662                 u64OldState = u64State = ASMAtomicReadU64(&pThis->u64State);
     661                u64OldState = u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    663662                uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0);
    664663                c--;
    665664                u64State &= ~RTCSRW_CNT_WR_MASK;
    666665                u64State |= c << RTCSRW_CNT_WR_SHIFT;
    667                 if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     666                if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    668667                    break;
    669668            }
     
    673672                                      (uint32_t)((u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT),
    674673                                      (uint32_t)((u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT),
    675                                       (void *)pThis->hNativeWriter);
     674                                      (void *)pThis->u.s.hNativeWriter);
    676675            return VERR_SEM_BUSY;
    677676        }
     
    685684                                     (uint32_t)((u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT),
    686685                                     (uint32_t)((u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT),
    687                                      (void *)pThis->hNativeWriter);
     686                                     (void *)pThis->u.s.hNativeWriter);
    688687        for (uint32_t iLoop = 0; ; iLoop++)
    689688        {
     
    712711                for (;;)
    713712                {
    714                     u64OldState = u64State = ASMAtomicReadU64(&pThis->u64State);
     713                    u64OldState = u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    715714                    uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0);
    716715                    c--;
    717716                    u64State &= ~RTCSRW_CNT_WR_MASK;
    718717                    u64State |= c << RTCSRW_CNT_WR_SHIFT;
    719                     if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     718                    if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    720719                        break;
    721720                }
     
    723722            }
    724723
    725             u64State = ASMAtomicReadU64(&pThis->u64State);
     724            u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    726725            if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    727726            {
    728                 ASMAtomicCmpXchgHandle(&pThis->hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
     727                ASMAtomicCmpXchgHandle(&pThis->u.s.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
    729728                if (fDone)
    730729                    break;
     
    737736     * Got it!
    738737     */
    739     Assert((ASMAtomicReadU64(&pThis->u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     738    Assert((ASMAtomicReadU64(&pThis->u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    740739    ASMAtomicWriteU32(&pThis->cWriteRecursions, 1);
    741740    Assert(pThis->cWriterReads == 0);
     
    806805    RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    807806    RTNATIVETHREAD hNativeWriter;
    808     ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     807    ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    809808    AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER);
    810809
     
    824823         */
    825824        ASMAtomicWriteU32(&pThis->cWriteRecursions, 0);
    826         ASMAtomicWriteHandle(&pThis->hNativeWriter, NIL_RTNATIVETHREAD);
    827 
    828         uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     825        ASMAtomicWriteHandle(&pThis->u.s.hNativeWriter, NIL_RTNATIVETHREAD);
     826
     827        uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    829828        IPRT_CRITSECTRW_EXCL_LEAVING(pThis, NULL, 0,
    830829                                     (uint32_t)((u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT),
     
    845844                u64State &= ~RTCSRW_CNT_WR_MASK;
    846845                u64State |= c << RTCSRW_CNT_WR_SHIFT;
    847                 if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     846                if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    848847                {
    849848                    if (c > 0)
     
    860859                u64State &= ~(RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    861860                u64State |= RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT;
    862                 if (ASMAtomicCmpXchgU64(&pThis->u64State, u64State, u64OldState))
     861                if (ASMAtomicCmpXchgU64(&pThis->u.s.u64State, u64State, u64OldState))
    863862                {
    864863                    Assert(!pThis->fNeedReset);
     
    873872            if (pThis->u32Magic != RTCRITSECTRW_MAGIC)
    874873                return VERR_SEM_DESTROYED;
    875             u64State = ASMAtomicReadU64(&pThis->u64State);
     874            u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    876875        }
    877876    }
     
    888887        if (IPRT_CRITSECTRW_EXCL_LEAVING_ENABLED())
    889888        {
    890             uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     889            uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    891890            IPRT_CRITSECTRW_EXCL_LEAVING(pThis, NULL, cNestings + pThis->cWriterReads,
    892891                                         (uint32_t)((u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT),
     
    919918    RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    920919    RTNATIVETHREAD hNativeWriter;
    921     ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter);
     920    ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hNativeWriter);
    922921    return hNativeWriter == hNativeSelf;
    923922}
     
    943942     * Inspect the state.
    944943     */
    945     uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     944    uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    946945    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    947946    {
     
    952951        RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
    953952        RTNATIVETHREAD hWriter;
    954         ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hWriter);
     953        ASMAtomicUoReadHandle(&pThis->u.s.hNativeWriter, &hWriter);
    955954        return hWriter == hNativeSelf;
    956955    }
     
    10201019     * Return the requested data.
    10211020     */
    1022     uint64_t u64State = ASMAtomicReadU64(&pThis->u64State);
     1021    uint64_t u64State = ASMAtomicReadU64(&pThis->u.s.u64State);
    10231022    if ((u64State & RTCSRW_DIR_MASK) != (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    10241023        return 0;
     
    10371036    //Assert(pThis->cNestings == 0);
    10381037    //Assert(pThis->cLockers == -1);
    1039     Assert(pThis->hNativeWriter == NIL_RTNATIVETHREAD);
     1038    Assert(pThis->u.s.hNativeWriter == NIL_RTNATIVETHREAD);
    10401039#ifdef IN_RING0
    10411040    Assert(pThis->fFlags & RTCRITSECT_FLAGS_RING0);
     
    10511050
    10521051    pThis->fFlags   = 0;
    1053     pThis->u64State = 0;
     1052    pThis->u.s.u64State = 0;
    10541053
    10551054    RTSEMEVENT      hEvtWrite = pThis->hEvtWrite;
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