VirtualBox

Changeset 90637 in vbox for trunk


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

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/critsect.h

    r90398 r90637  
    397397    uint16_t                            fFlags;
    398398
    399     /** The state variable.
    400      * All accesses are atomic and it bits are defined like this:
    401      *      Bits 0..14  - cReads.
    402      *      Bit 15      - Unused.
    403      *      Bits 16..31 - cWrites. - doesn't make sense here
    404      *      Bit 31      - fDirection; 0=Read, 1=Write.
    405      *      Bits 32..46 - cWaitingReads
    406      *      Bit 47      - Unused.
    407      *      Bits 48..62 - cWaitingWrites
    408      *      Bit 63      - Unused.
    409      */
    410     uint64_t volatile                   u64State;
    411     /** The write owner. */
    412     RTNATIVETHREAD volatile             hNativeWriter;
    413399    /** The number of reads made by the current writer. */
    414400    uint32_t volatile                   cWriterReads;
     
    416402     *  of the lock counts as the first one.) */
    417403    uint32_t volatile                   cWriteRecursions;
     404    /** Union that allows us to atomically update both the state and
     405     * exclusive owner if the hardware supports cmpxchg16b or similar. */
     406    union
     407    {
     408        struct
     409        {
     410            /** The state variable.
     411             * All accesses are atomic and it bits are defined like this:
     412             *      Bits 0..14  - cReads.
     413             *      Bit 15      - Unused.
     414             *      Bits 16..31 - cWrites.
     415             *      Bit 31      - fDirection; 0=Read, 1=Write.
     416             *      Bits 32..46 - cWaitingReads
     417             *      Bit 47      - Unused.
     418             *      Bits 48..62 - cWaitingWrites - doesn't make sense here, not used.
     419             *      Bit 63      - Unused.
     420             */
     421            uint64_t volatile           u64State;
     422            /** The write owner. */
     423            RTNATIVETHREAD volatile     hNativeWriter;
     424        } s;
     425        RTUINT128U volatile             u128;
     426    } u;
    418427
    419428    /** What the writer threads are blocking on. */
     
    427436    /** The validator record for the readers. */
    428437    R3R0PTRTYPE(PRTLOCKVALRECSHRD)      pValidatorRead;
    429 #if HC_ARCH_BITS == 32
    430     /** Size padding.  */
    431     RTHCPTR                             HCPtrPadding;
    432 #endif
    433438} RTCRITSECTRW;
    434439AssertCompileSize(RTCRITSECTRW, HC_ARCH_BITS == 32 ? 48 : 64);
  • 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;
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp

    r90636 r90637  
    186186        int            rc9;
    187187        RTNATIVETHREAD hNativeWriter;
    188         ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     188        ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    189189        if (hNativeWriter != NIL_RTTHREAD && hNativeWriter == pdmCritSectRwGetNativeSelf(pVM, pThis))
    190190            rc9 = RTLockValidatorRecExclCheckOrder(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);
     
    199199     * Get cracking...
    200200     */
    201     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u64State);
     201    uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    202202    uint64_t u64OldState = u64State;
    203203
     
    213213            u64State &= ~RTCSRW_CNT_RD_MASK;
    214214            u64State |= c << RTCSRW_CNT_RD_SHIFT;
    215             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     215            if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    216216            {
    217217#if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)
     
    227227            u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    228228            u64State |= (UINT64_C(1) << RTCSRW_CNT_RD_SHIFT) | (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT);
    229             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     229            if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    230230            {
    231231                Assert(!pThis->s.Core.fNeedReset);
     
    241241            /* Is the writer perhaps doing a read recursion? */
    242242            RTNATIVETHREAD hNativeWriter;
    243             ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     243            ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    244244            if (hNativeWriter != NIL_RTNATIVETHREAD)
    245245            {
     
    296296                u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT);
    297297
    298                 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     298                if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    299299                {
    300300                    for (uint32_t iLoop = 0; ; iLoop++)
     
    335335                            for (;;)
    336336                            {
    337                                 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     337                                u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    338338                                c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT;
    339339                                AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid read count on bailout"));
     
    344344                                u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_WAIT_CNT_RD_MASK);
    345345                                u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT);
    346                                 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     346                                if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    347347                                    break;
    348348                            }
     
    351351
    352352                        Assert(pThis->s.Core.fNeedReset);
    353                         u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     353                        u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    354354                        if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    355355                            break;
     
    368368                        u64State |= cWait << RTCSRW_WAIT_CNT_RD_SHIFT;
    369369
    370                         if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     370                        if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    371371                        {
    372372                            if (cWait == 0)
     
    380380                            break;
    381381                        }
    382                         u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     382                        u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    383383                    }
    384384
     
    417417
    418418        ASMNopPause();
    419         u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     419        u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    420420        u64OldState = u64State;
    421421    }
     
    423423    /* got it! */
    424424    STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(Stat,EnterShared));
    425     Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
     425    Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));
    426426    return VINF_SUCCESS;
    427427
     
    596596     * Check the direction and take action accordingly.
    597597     */
    598     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u64State);
     598    uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    599599    uint64_t u64OldState = u64State;
    600600    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
     
    622622                u64State &= ~RTCSRW_CNT_RD_MASK;
    623623                u64State |= c << RTCSRW_CNT_RD_SHIFT;
    624                 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     624                if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    625625                    break;
    626626            }
     
    636636                    u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_DIR_MASK);
    637637                    u64State |= RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT;
    638                     if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     638                    if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    639639                    {
    640640                        int rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite);
     
    672672
    673673            ASMNopPause();
    674             u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     674            u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    675675            u64OldState = u64State;
    676676        }
     
    685685
    686686        RTNATIVETHREAD hNativeWriter;
    687         ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     687        ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    688688        AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER);
    689689        AssertReturn(pThis->s.Core.cWriterReads > 0, VERR_NOT_OWNER);
     
    750750    for (;;)
    751751    {
    752         uint64_t       u64State    = ASMAtomicReadU64(&pThis->s.Core.u64State);
     752        uint64_t       u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    753753        uint64_t const u64OldState = u64State;
    754754        uint64_t c                 = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT;
     
    757757        u64State &= ~RTCSRW_CNT_WR_MASK;
    758758        u64State |= c << RTCSRW_CNT_WR_SHIFT;
    759         if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     759        if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    760760            return rc;
    761761
     
    774774{
    775775    RT_NOREF(hThreadSelf, fNoVal, pSrcPos);
    776     Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     776    Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    777777
    778778#if 1 /** @todo consider generating less noise... */
     
    847847               : SUPSemEventWait(pSession, hEvent, cMsMaxOne);
    848848            Log11Func(("%p: rc=%Rrc %'RU64 ns (cMsMaxOne=%RU64 hNativeWriter=%p)\n",
    849                        pThis, rc, RTTimeNanoTS() - tsStart, cMsMaxOne, pThis->s.Core.hNativeWriter));
     849                       pThis, rc, RTTimeNanoTS() - tsStart, cMsMaxOne, pThis->s.Core.u.s.hNativeWriter));
    850850# endif
    851851            if (RT_LIKELY(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC))
     
    939939         * Try take exclusive write ownership.
    940940         */
    941         uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     941        uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    942942        if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    943943        {
    944944            bool fDone;
    945             ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
     945            ASMAtomicCmpXchgHandle(&pThis->s.Core.u.s.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
    946946            if (fDone)
    947947                return pdmCritSectRwEnterExclFirst(pThis, pSrcPos, fNoVal, hThreadSelf);
     
    990990    AssertReturn(hNativeSelf != NIL_RTNATIVETHREAD, VERR_VM_THREAD_NOT_EMT);
    991991    RTNATIVETHREAD hNativeWriter;
    992     ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     992    ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    993993    if (hNativeSelf == hNativeWriter)
    994994    {
    995         Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
     995        Assert((ASMAtomicReadU64(&pThis->s.Core.u.s.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));
    996996#if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3)
    997997        if (!fNoVal)
     
    10131013     * Get cracking.
    10141014     */
    1015     uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u64State);
     1015    uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    10161016    uint64_t u64OldState = u64State;
    10171017
     
    10281028            u64State &= ~RTCSRW_CNT_WR_MASK;
    10291029            u64State |= c << RTCSRW_CNT_WR_SHIFT;
    1030             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     1030            if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    10311031                break;
    10321032        }
     
    10361036            u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    10371037            u64State |= (UINT64_C(1) << RTCSRW_CNT_WR_SHIFT) | (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT);
    1038             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     1038            if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    10391039                break;
    10401040        }
     
    10541054            u64State &= ~RTCSRW_CNT_WR_MASK;
    10551055            u64State |= c << RTCSRW_CNT_WR_SHIFT;
    1056             if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     1056            if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    10571057                break;
    10581058        }
     
    10661066
    10671067        ASMNopPause();
    1068         u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     1068        u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    10691069        u64OldState = u64State;
    10701070    }
     
    10821082    if (fDone)
    10831083    {
    1084         ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
     1084        ASMAtomicCmpXchgHandle(&pThis->s.Core.u.s.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);
    10851085        if (fDone)
    10861086            return pdmCritSectRwEnterExclFirst(pThis, pSrcPos, fNoVal, hThreadSelf);
     
    13261326
    13271327    RTNATIVETHREAD hNativeWriter;
    1328     ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     1328    ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    13291329    AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER);
    13301330
     
    13561356            ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0);
    13571357            STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);
    1358             ASMAtomicWriteHandle(&pThis->s.Core.hNativeWriter, NIL_RTNATIVETHREAD);
     1358            ASMAtomicWriteHandle(&pThis->s.Core.u.s.hNativeWriter, NIL_RTNATIVETHREAD);
    13591359
    13601360            for (;;)
    13611361            {
    1362                 uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u64State);
     1362                uint64_t u64State    = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    13631363                uint64_t u64OldState = u64State;
    13641364
     
    13731373                    u64State &= ~RTCSRW_CNT_WR_MASK;
    13741374                    u64State |= c << RTCSRW_CNT_WR_SHIFT;
    1375                     if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     1375                    if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    13761376                    {
    13771377                        if (c > 0)
     
    13881388                    u64State &= ~(RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);
    13891389                    u64State |= RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT;
    1390                     if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState))
     1390                    if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))
    13911391                    {
    13921392                        Assert(!pThis->s.Core.fNeedReset);
     
    15071507     */
    15081508    RTNATIVETHREAD hNativeWriter;
    1509     ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter);
     1509    ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hNativeWriter);
    15101510    if (hNativeWriter == NIL_RTNATIVETHREAD)
    15111511        return false;
     
    15451545     * Inspect the state.
    15461546     */
    1547     uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     1547    uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    15481548    if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT))
    15491549    {
     
    15531553         */
    15541554        RTNATIVETHREAD hWriter;
    1555         ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hWriter);
     1555        ASMAtomicUoReadHandle(&pThis->s.Core.u.s.hNativeWriter, &hWriter);
    15561556        if (hWriter == NIL_RTNATIVETHREAD)
    15571557            return false;
     
    16491649     * Return the requested data.
    16501650     */
    1651     uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State);
     1651    uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u.s.u64State);
    16521652    if ((u64State & RTCSRW_DIR_MASK) != (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))
    16531653        return 0;
  • trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp

    r90634 r90637  
    291291                    pCritSect->Core.afPadding[0]         = false;
    292292                    pCritSect->Core.fFlags               = 0;
    293                     pCritSect->Core.u64State             = 0;
    294                     pCritSect->Core.hNativeWriter        = NIL_RTNATIVETHREAD;
     293                    pCritSect->Core.u.u128.s.Lo          = 0;
     294                    pCritSect->Core.u.u128.s.Hi          = 0;
     295                    pCritSect->Core.u.s.hNativeWriter    = NIL_RTNATIVETHREAD;
    295296                    pCritSect->Core.cWriterReads         = 0;
    296297                    pCritSect->Core.cWriteRecursions     = 0;
    297 #if HC_ARCH_BITS == 32
    298                     pCritSect->Core.HCPtrPadding         = NIL_RTHCPTR;
    299 #endif
    300298                    pCritSect->pvKey                     = pvKey;
    301299                    pCritSect->pszName                   = pszName;
     
    583581    //Assert(pCritSect->Core.cNestings == 0);
    584582    //Assert(pCritSect->Core.cLockers == -1);
    585     Assert(pCritSect->Core.hNativeWriter == NIL_RTNATIVETHREAD);
     583    Assert(pCritSect->Core.u.s.hNativeWriter == NIL_RTNATIVETHREAD);
    586584
    587585    /*
     
    603601     * In case someone is waiting we'll signal the semaphore cLockers + 1 times.
    604602     */
    605     pCritSect->Core.fFlags   = 0;
    606     pCritSect->Core.u64State = 0;
     603    pCritSect->Core.fFlags       = 0;
     604    pCritSect->Core.u.s.u64State = 0;
    607605
    608606    SUPSEMEVENT      hEvtWrite = (SUPSEMEVENT)pCritSect->Core.hEvtWrite;
     
    10181016         pCur = pCur->pNext)
    10191017    {
    1020         if (   pCur->Core.hNativeWriter == hNativeThread
     1018        if (   pCur->Core.u.s.hNativeWriter == hNativeThread
    10211019            || PDMCritSectRwIsReadOwner(pVM, (PPDMCRITSECTRW)pCur, false /*fWannaHear*/) )
    10221020        {
     
    12101208            do
    12111209            {
    1212                 u64State         = pCritSect->Core.u64State;
    1213                 hOwner           = pCritSect->Core.hNativeWriter;
     1210                u64State         = pCritSect->Core.u.s.u64State;
     1211                hOwner           = pCritSect->Core.u.s.hNativeWriter;
    12141212                cWriterReads     = pCritSect->Core.cWriterReads;
    12151213                cWriteRecursions = pCritSect->Core.cWriteRecursions;
     
    12171215                uMagic           = pCritSect->Core.u32Magic;
    12181216            } while (   cTries-- > 0
    1219                      && (   u64State         != pCritSect->Core.u64State
    1220                          || hOwner           != pCritSect->Core.hNativeWriter
     1217                     && (   u64State         != pCritSect->Core.u.s.u64State
     1218                         || hOwner           != pCritSect->Core.u.s.hNativeWriter
    12211219                         || cWriterReads     != pCritSect->Core.cWriterReads
    12221220                         || cWriteRecursions != pCritSect->Core.cWriteRecursions
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r90634 r90637  
    513513} PDMCRITSECTRWINT;
    514514AssertCompileMemberAlignment(PDMCRITSECTRWINT, StatContentionRZEnterExcl, 8);
    515 AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u64State, 8);
     515AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u, 16);
     516AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u.s.u64State, 8);
    516517/** Pointer to private critical section data. */
    517518typedef PDMCRITSECTRWINT *PPDMCRITSECTRWINT;
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