VirtualBox

Changeset 26814 in vbox


Ignore:
Timestamp:
Feb 25, 2010 10:44:22 PM (15 years ago)
Author:
vboxsync
Message:

AsyncCompletion: Protect the dirty but not committed list by a spinlock

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp

    r26812 r26814  
    637637    RTSemRWRequestWrite(pEndpointCache->SemRWEntries, RT_INDEFINITE_WAIT);
    638638
    639     if (!RTListIsEmpty(&pEndpointCache->ListDirtyNotCommitted))
    640     {
    641         PPDMACFILECACHEENTRY pEntry = RTListNodeGetFirst(&pEndpointCache->ListDirtyNotCommitted,
     639    /* The list is moved to a new header to reduce locking overhead. */
     640    RTLISTNODE ListDirtyNotCommitted;
     641    RTSPINLOCKTMP Tmp;
     642
     643    RTListInit(&ListDirtyNotCommitted);
     644    RTSpinlockAcquire(pEndpointCache->LockList, &Tmp);
     645    RTListMove(&ListDirtyNotCommitted, &pEndpointCache->ListDirtyNotCommitted);
     646    RTSpinlockRelease(pEndpointCache->LockList, &Tmp);
     647
     648    if (!RTListIsEmpty(&ListDirtyNotCommitted))
     649    {
     650        PPDMACFILECACHEENTRY pEntry = RTListNodeGetFirst(&ListDirtyNotCommitted,
    642651                                                         PDMACFILECACHEENTRY,
    643652                                                         NodeNotCommitted);
    644653
    645         while (!RTListNodeIsLast(&pEndpointCache->ListDirtyNotCommitted, &pEntry->NodeNotCommitted))
     654        while (!RTListNodeIsLast(&ListDirtyNotCommitted, &pEntry->NodeNotCommitted))
    646655        {
    647656            PPDMACFILECACHEENTRY pNext = RTListNodeGetNext(&pEntry->NodeNotCommitted, PDMACFILECACHEENTRY,
     
    654663
    655664        /* Commit the last endpoint */
    656         Assert(RTListNodeIsLast(&pEndpointCache->ListDirtyNotCommitted, &pEntry->NodeNotCommitted));
     665        Assert(RTListNodeIsLast(&ListDirtyNotCommitted, &pEntry->NodeNotCommitted));
    657666        pdmacFileCacheEntryCommit(pEndpointCache, pEntry);
    658667        RTListNodeRemove(&pEntry->NodeNotCommitted);
    659         AssertMsg(RTListIsEmpty(&pEndpointCache->ListDirtyNotCommitted),
     668        AssertMsg(RTListIsEmpty(&ListDirtyNotCommitted),
    660669                  ("Committed all entries but list is not empty\n"));
    661670    }
     
    725734    {
    726735        pEntry->fFlags |= PDMACFILECACHE_ENTRY_IS_DIRTY;
     736
     737        RTSPINLOCKTMP Tmp;
     738        RTSpinlockAcquire(pEndpointCache->LockList, &Tmp);
    727739        RTListAppend(&pEndpointCache->ListDirtyNotCommitted, &pEntry->NodeNotCommitted);
     740        RTSpinlockRelease(pEndpointCache->LockList, &Tmp);
     741
    728742        uint32_t cbDirty = ASMAtomicAddU32(&pCache->cbDirty, pEntry->cbData);
    729743
     
    10551069    pEndpointCache->pCache = &pClassFile->Cache;
    10561070    RTListInit(&pEndpointCache->ListDirtyNotCommitted);
    1057 
    1058     int rc = RTSemRWCreate(&pEndpointCache->SemRWEntries);
     1071    int rc = RTSpinlockCreate(&pEndpointCache->LockList);
     1072
    10591073    if (RT_SUCCESS(rc))
    10601074    {
    1061         pEndpointCache->pTree  = (PAVLRFOFFTREE)RTMemAllocZ(sizeof(AVLRFOFFTREE));
    1062         if (pEndpointCache->pTree)
     1075        rc = RTSemRWCreate(&pEndpointCache->SemRWEntries);
     1076        if (RT_SUCCESS(rc))
    10631077        {
    1064             pClassFile->Cache.cRefs++;
    1065             RTListAppend(&pClassFile->Cache.ListEndpoints, &pEndpointCache->NodeCacheEndpoint);
    1066 
    1067             /* Arm the timer if this is the first endpoint. */
    1068             if (   pClassFile->Cache.cRefs == 1
    1069                 && pClassFile->Cache.u32CommitTimeoutMs > 0)
    1070                 rc = TMTimerSetMillies(pClassFile->Cache.pTimerCommit, pClassFile->Cache.u32CommitTimeoutMs);
     1078            pEndpointCache->pTree  = (PAVLRFOFFTREE)RTMemAllocZ(sizeof(AVLRFOFFTREE));
     1079            if (pEndpointCache->pTree)
     1080            {
     1081                pClassFile->Cache.cRefs++;
     1082                RTListAppend(&pClassFile->Cache.ListEndpoints, &pEndpointCache->NodeCacheEndpoint);
     1083
     1084                /* Arm the timer if this is the first endpoint. */
     1085                if (   pClassFile->Cache.cRefs == 1
     1086                    && pClassFile->Cache.u32CommitTimeoutMs > 0)
     1087                    rc = TMTimerSetMillies(pClassFile->Cache.pTimerCommit, pClassFile->Cache.u32CommitTimeoutMs);
     1088            }
     1089            else
     1090                rc = VERR_NO_MEMORY;
     1091
     1092            if (RT_FAILURE(rc))
     1093                RTSemRWDestroy(pEndpointCache->SemRWEntries);
    10711094        }
    1072         else
    1073             rc = VERR_NO_MEMORY;
    10741095
    10751096        if (RT_FAILURE(rc))
    1076             RTSemRWDestroy(pEndpointCache->SemRWEntries);
     1097            RTSpinlockDestroy(pEndpointCache->LockList);
    10771098    }
    10781099
     
    11441165    RTAvlrFileOffsetDestroy(pEndpointCache->pTree, pdmacFileEpCacheEntryDestroy, pCache);
    11451166    RTSemRWReleaseWrite(pEndpointCache->SemRWEntries);
     1167
     1168    RTSpinlockDestroy(pEndpointCache->LockList);
    11461169
    11471170    pCache->cRefs--;
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r26812 r26814  
    3333#include <iprt/avl.h>
    3434#include <iprt/list.h>
     35#include <iprt/spinlock.h>
    3536
    3637#include "PDMAsyncCompletionInternal.h"
     
    385386    /** Handle of the flush request if one is active */
    386387    volatile PPDMASYNCCOMPLETIONTASKFILE pTaskFlush;
     388    /** Lock protecting the dirty entries list. */
     389    RTSPINLOCK                           LockList;
    387390    /** List of dirty but not committed entries for this endpoint. */
    388391    RTLISTNODE                           ListDirtyNotCommitted;
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