VirtualBox

Changeset 20867 in vbox for trunk


Ignore:
Timestamp:
Jun 24, 2009 12:09:39 AM (15 years ago)
Author:
vboxsync
Message:

REMR3ReplayHandlerNotifications: Fixed list reversal regression from r48863.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/VBoxRecompiler.c

    r20845 r20867  
    250250REMR3DECL(int) REMR3Init(PVM pVM)
    251251{
    252     uint32_t u32Dummy;
    253     int rc;
     252    PREMHANDLERNOTIFICATION pCur;
     253    uint32_t                u32Dummy;
     254    int                     rc;
     255    unsigned                i;
    254256
    255257#ifdef VBOX_ENABLE_VBOXREM64
     
    420422#endif
    421423
    422     PREMHANDLERNOTIFICATION pCur;
    423     unsigned i;
    424 
    425     pVM->rem.s.idxPendingList = -1;
     424    /*
     425     * Init the handler notification lists.
     426     */
     427    pVM->rem.s.idxPendingList = UINT32_MAX;
    426428    pVM->rem.s.idxFreeList    = 0;
    427429
    428     for (i = 0 ; i < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1; i++)
     430    for (i = 0 ; i < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications); i++)
    429431    {
    430432        pCur = &pVM->rem.s.aHandlerNotifications[i];
     
    432434        pCur->idxSelf = i;
    433435    }
    434 
    435     pCur = &pVM->rem.s.aHandlerNotifications[RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1];
    436     pCur->idxNext = -1;
    437     pCur->idxSelf = RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1;
     436    pCur->idxNext = UINT32_MAX;         /* the last record. */
    438437
    439438    return rc;
     
    27302729    if (VM_FF_TESTANDCLEAR(pVM, VM_FF_REM_HANDLER_NOTIFY_BIT))
    27312730    {
    2732         PREMHANDLERNOTIFICATION pReqsRev;
    2733         PREMHANDLERNOTIFICATION pReqs;
    2734         uint32_t                idxNext;
    2735         uint32_t                idxReqs;
     2731        uint32_t    idxNext;
     2732        uint32_t    idxRevHead;
     2733        uint32_t    idxHead;
     2734#ifdef VBOX_STRICT
     2735        int32_t     c = 0;
     2736#endif
    27362737
    27372738        /* Lockless purging of pending notifications. */
    2738         idxReqs = ASMAtomicXchgU32(&pVM->rem.s.idxPendingList, UINT32_MAX);
    2739         if (idxReqs == UINT32_MAX)
     2739        idxHead = ASMAtomicXchgU32(&pVM->rem.s.idxPendingList, UINT32_MAX);
     2740        if (idxHead == UINT32_MAX)
    27402741            return;
    2741         Assert(idxReqs < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
     2742        Assert(idxHead < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
    27422743
    27432744        /*
    27442745         * Reverse the list to process it in FIFO order.
    27452746         */
    2746         pReqsRev = &pVM->rem.s.aHandlerNotifications[idxReqs];
    2747         pReqs    = NULL;
    2748         while (pReqsRev)
     2747        idxRevHead = UINT32_MAX;
     2748        do
    27492749        {
    2750             PREMHANDLERNOTIFICATION pCur = pReqsRev;
    2751             idxNext = pReqsRev->idxNext;
    2752             if (idxNext != UINT32_MAX)
    2753             {
    2754                 Assert(idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
    2755                 pReqsRev = &pVM->rem.s.aHandlerNotifications[idxNext];
    2756             }
    2757             else
    2758                 pReqsRev = NULL;
    2759             pCur->idxNext = idxNext;
    2760             pReqs = pCur;
    2761         }
     2750            /* Save the index of the next rec. */
     2751            idxNext    = pVM->rem.s.aHandlerNotifications[idxHead].idxNext;
     2752            Assert(idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) || idxNext == UINT32_MAX);
     2753            /* Push the record onto the reversed list. */
     2754            pVM->rem.s.aHandlerNotifications[idxHead].idxNext = idxRevHead;
     2755            idxRevHead = idxHead;
     2756            Assert(++c <= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
     2757            /* Advance. */
     2758            idxHead    = idxNext;
     2759        } while (idxHead != UINT32_MAX);
    27622760
    27632761        /*
     
    27652763         * processed to avoid having other EMTs running out of entries while we're flushing.
    27662764         */
    2767         while (pReqs)
     2765        idxHead = idxRevHead;
     2766        do
    27682767        {
    2769             PREMHANDLERNOTIFICATION pCur = pReqs;
     2768            PREMHANDLERNOTIFICATION pCur = &pVM->rem.s.aHandlerNotifications[idxHead];
     2769            uint32_t                idxCur;
     2770            Assert(--c >= 0);
    27702771
    27712772            switch (pCur->enmKind)
     
    28042805
    28052806            /*
    2806              * Advance pReqs.
     2807             * Advance idxHead.
    28072808             */
    2808             idxNext = pCur->idxNext;
    2809             if (idxNext != UINT32_MAX)
    2810             {
    2811                 AssertMsg(idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications), ("idxNext=%d\n", idxNext));
    2812                 pReqs = &pVM->rem.s.aHandlerNotifications[idxNext];
    2813             }
    2814             else
    2815                 pReqs = NULL;
     2809            idxCur  = idxHead;
     2810            idxHead = pCur->idxNext;
     2811            Assert(idxHead < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) || (idxHead == UINT32_MAX && c == 0));
    28162812
    28172813            /*
     
    28232819                ASMAtomicWriteU32(&pCur->idxNext, idxNext);
    28242820                ASMCompilerBarrier();
    2825             } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pCur->idxSelf, idxNext));
     2821            } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, idxCur, idxNext));
     2822        } while (idxHead != UINT32_MAX);
     2823
     2824#ifdef VBOX_STRICT
     2825        if (pVM->cCPUs == 1)
     2826        {
     2827            /* Check that all records are now on the free list. */
     2828            for (c = 0, idxNext = pVM->rem.s.idxFreeList; idxNext != UINT32_MAX;
     2829                 idxNext = pVM->rem.s.aHandlerNotifications[idxNext].idxNext)
     2830                c++;
     2831            AssertMsg(c == RT_ELEMENTS(pVM->rem.s.aHandlerNotifications), ("%#x != %#x, idxFreeList=%#x\n", c, RT_ELEMENTS(pVM->rem.s.aHandlerNotifications), pVM->rem.s.idxFreeList));
    28262832        }
     2833#endif
    28272834    }
    28282835}
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