VirtualBox

Changeset 21035 in vbox


Ignore:
Timestamp:
Jun 29, 2009 3:45:43 PM (15 years ago)
Author:
vboxsync
Message:

Fixed concurrent pdm queue flushing.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMInternal.h

    r20374 r21035  
    888888     * Only touched by EMT. */
    889889    RCPTRTYPE(struct PDMQUEUE *)    pQueueFlushRC;
    890 #if HC_ARCH_BITS == 64
    891     RTRCPTR                         uPadding2;
    892 #endif
     890    /** Set if we're currently checking queues to prevent other VCPUs from doing the same concurrently. */
     891    volatile uint32_t               fQueueFlushing;
    893892
    894893    /** Head of the PDM Thread list. (singly linked) */
  • trunk/src/VBox/VMM/PDMQueue.cpp

    r20889 r21035  
    627627    LogFlow(("PDMR3QueuesFlush:\n"));
    628628
    629     /* Use atomic test and clear to prevent useless checks; pdmR3QueueFlush is SMP safe. */
    630     if (VM_FF_TESTANDCLEAR(pVM, VM_FF_PDM_QUEUES_BIT))
    631     {
     629    VM_FF_CLEAR(pVM, VM_FF_PDM_QUEUES);
     630
     631    /* Prevent other VCPUs from flushing queues at the same time; we'll never flush an item twice, but the order might change. */
     632    if (ASMAtomicCmpXchgU32(&pVM->pdm.s.fQueueFlushing, 1, 0))
     633    {
     634        /* Use atomic test and clear to prevent useless checks; pdmR3QueueFlush is SMP safe. */
     635        do
     636        {
     637            for (PPDMQUEUE pCur = pVM->pdm.s.pQueuesForced; pCur; pCur = pCur->pNext)
     638            {
     639                if (    pCur->pPendingR3
     640                    ||  pCur->pPendingR0
     641                    ||  pCur->pPendingRC)
     642                {
     643                    if (    pdmR3QueueFlush(pCur)
     644                        &&  (   pCur->pPendingR3
     645                             || pCur->pPendingR0))
     646                        /* new items arrived while flushing. */
     647                        pdmR3QueueFlush(pCur);
     648                }
     649            }
     650        }
     651        while (VM_FF_TESTANDCLEAR(pVM, VM_FF_PDM_QUEUES_BIT));
     652
     653        ASMAtomicXchgU32(&pVM->pdm.s.fQueueFlushing, 0);
     654
     655        /* Check if we missed anything. */
    632656        for (PPDMQUEUE pCur = pVM->pdm.s.pQueuesForced; pCur; pCur = pCur->pNext)
    633657        {
     
    636660                ||  pCur->pPendingRC)
    637661            {
    638                 if (    pdmR3QueueFlush(pCur)
    639                     &&  pCur->pPendingR3)
    640                     /* new items arrived while flushing. */
    641                     pdmR3QueueFlush(pCur);
     662                VM_FF_SET(pVM, VM_FF_PDM_QUEUES);
     663                break;
    642664            }
    643665        }
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