VirtualBox

Changeset 25147 in vbox for trunk/src


Ignore:
Timestamp:
Dec 2, 2009 1:42:32 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
55558
Message:

AsyncCompletion/Cache: Complete all pending writes before completing a flush

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

Legend:

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

    r24443 r25147  
    850850                            PPDMASYNCCOMPLETIONENDPOINT pEndpoint)
    851851{
     852    int rc = VINF_SUCCESS;
    852853    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint;
    853854    PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pTask;
     
    858859    pTaskFile->cbTransferLeft = 0;
    859860
    860     PPDMACTASKFILE pIoTask = pdmacFileTaskAlloc(pEpFile);
    861     AssertPtr(pIoTask);
    862 
    863     pIoTask->pEndpoint       = pEpFile;
    864     pIoTask->enmTransferType = PDMACTASKFILETRANSFER_FLUSH;
    865     pIoTask->pvUser          = pTaskFile;
    866     pIoTask->pfnCompleted    = pdmacFileEpTaskCompleted;
    867     pdmacFileEpAddTask(pEpFile, pIoTask);
    868 
    869     return VINF_SUCCESS;
     861    if (pEpFile->fCaching)
     862        rc = pdmacFileEpCacheFlush(pEpFile, pTaskFile);
     863    else
     864    {
     865        PPDMACTASKFILE pIoTask = pdmacFileTaskAlloc(pEpFile);
     866        AssertPtr(pIoTask);
     867
     868        pIoTask->pEndpoint       = pEpFile;
     869        pIoTask->enmTransferType = PDMACTASKFILETRANSFER_FLUSH;
     870        pIoTask->pvUser          = pTaskFile;
     871        pIoTask->pfnCompleted    = pdmacFileEpTaskCompleted;
     872        pdmacFileEpAddTask(pEpFile, pIoTask);
     873    }
     874
     875    return rc;
    870876}
    871877
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp

    r24708 r25147  
    563563
    564564/**
     565 * Completes a task segment freeing all ressources and completes the task handle
     566 * if everything was transfered.
     567 *
     568 * @returns Next task segment handle.
     569 * @param   pEndpointCache    The endpoint cache.
     570 * @param   pTaskSeg          Task segment to complete.
     571 */
     572static PPDMACFILETASKSEG pdmacFileCacheTaskComplete(PPDMACFILEENDPOINTCACHE pEndpointCache, PPDMACFILETASKSEG pTaskSeg)
     573{
     574    PPDMACFILETASKSEG pNext = pTaskSeg->pNext;
     575
     576    uint32_t uOld = ASMAtomicSubU32(&pTaskSeg->pTask->cbTransferLeft, pTaskSeg->cbTransfer);
     577    AssertMsg(uOld >= pTaskSeg->cbTransfer, ("New value would overflow\n"));
     578    if (!(uOld - pTaskSeg->cbTransfer)
     579        && !ASMAtomicXchgBool(&pTaskSeg->pTask->fCompleted, true))
     580    {
     581        pdmR3AsyncCompletionCompleteTask(&pTaskSeg->pTask->Core);
     582
     583        if (pTaskSeg->fWrite)
     584        {
     585            /* Complete a pending flush if all writes have completed */
     586            uint32_t cWritesOutstanding = ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
     587            PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
     588
     589            if (!cWritesOutstanding && pTaskFlush)
     590                pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core);
     591        }
     592    }
     593
     594    RTMemFree(pTaskSeg);
     595
     596    return pNext;
     597}
     598
     599/**
    565600 * Completion callback for I/O tasks.
    566601 *
     
    613648                pEntry->fFlags |= PDMACFILECACHE_ENTRY_IS_DIRTY;
    614649
    615                 uint32_t uOld = ASMAtomicSubU32(&pCurr->pTask->cbTransferLeft, pCurr->cbTransfer);
    616                 AssertMsg(uOld >= pCurr->cbTransfer, ("New value would overflow\n"));
    617                 if (!(uOld - pCurr->cbTransfer)
    618                     && !ASMAtomicXchgBool(&pCurr->pTask->fCompleted, true))
    619                     pdmR3AsyncCompletionCompleteTask(&pCurr->pTask->Core);
    620 
    621                 PPDMACFILETASKSEG pFree = pCurr;
    622                 pCurr = pCurr->pNext;
    623 
    624                 RTMemFree(pFree);
     650                pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr);
    625651            }
    626652        }
     
    641667                memcpy(pCurr->pvBuf, pEntry->pbData + pCurr->uBufOffset, pCurr->cbTransfer);
    642668
    643             uint32_t uOld = ASMAtomicSubU32(&pCurr->pTask->cbTransferLeft, pCurr->cbTransfer);
    644             AssertMsg(uOld >= pCurr->cbTransfer, ("New value would overflow\n"));
    645             if (!(uOld - pCurr->cbTransfer)
    646                 && !ASMAtomicXchgBool(&pCurr->pTask->fCompleted, true))
    647                 pdmR3AsyncCompletionCompleteTask(&pCurr->pTask->Core);
    648 
    649             PPDMACFILETASKSEG pFree = pCurr;
    650             pCurr = pCurr->pNext;
    651 
    652             RTMemFree(pFree);
     669            pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr);
    653670        }
    654671    }
     
    15081525    /* Set to completed to make sure that the task is valid while we access it. */
    15091526    ASMAtomicWriteBool(&pTask->fCompleted, true);
     1527    ASMAtomicIncU32(&pEndpointCache->cWritesOutstanding);
    15101528
    15111529    int iSegCurr       = 0;
     
    19091927    if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0
    19101928        && !ASMAtomicXchgBool(&pTask->fCompleted, true))
     1929    {
    19111930        pdmR3AsyncCompletionCompleteTask(&pTask->Core);
    19121931
     1932        /* Complete a pending flush if all writes have completed */
     1933        uint32_t cWritesOutstanding = ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
     1934        PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
     1935
     1936        if (!cWritesOutstanding && pTaskFlush)
     1937            pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core);
     1938    }
     1939
    19131940    return VINF_SUCCESS;
    19141941}
     
    19161943#undef ADVANCE_SEGMENT_BUFFER
    19171944
     1945int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask)
     1946{
     1947    int rc = VINF_SUCCESS;
     1948
     1949    if (ASMAtomicReadPtr((void * volatile *)&pEndpoint->DataCache.pTaskFlush))
     1950        rc = VERR_RESOURCE_BUSY;
     1951    else
     1952    {
     1953        if (ASMAtomicReadU32(&pEndpoint->DataCache.cWritesOutstanding) > 0)
     1954            ASMAtomicWritePtr((void * volatile *)&pEndpoint->DataCache.pTaskFlush, pTask);
     1955        else
     1956            pdmR3AsyncCompletionCompleteTask(&pTask->Core);
     1957    }
     1958
     1959    return rc;
     1960}
     1961
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r24621 r25147  
    324324{
    325325    /** AVL tree managing cache entries. */
    326     PAVLRFOFFTREE         pTree;
     326    PAVLRFOFFTREE                        pTree;
    327327    /** R/W semaphore protecting cached entries for this endpoint. */
    328     RTSEMRW               SemRWEntries;
     328    RTSEMRW                              SemRWEntries;
    329329    /** Pointer to the gobal cache data */
    330     PPDMACFILECACHEGLOBAL pCache;
    331 
     330    PPDMACFILECACHEGLOBAL                pCache;
     331    /** Number of writes outstanding. */
     332    volatile uint32_t                    cWritesOutstanding;
     333    /** Handle of the flush request if one is active */
     334    volatile PPDMASYNCCOMPLETIONTASKFILE pTaskFlush;
    332335#ifdef VBOX_WITH_STATISTICS
    333336    /** Number of times a write was deferred because the cache entry was still in progress */
    334     STAMCOUNTER           StatWriteDeferred;
     337    STAMCOUNTER                          StatWriteDeferred;
    335338#endif
    336339} PDMACFILEENDPOINTCACHE, *PPDMACFILEENDPOINTCACHE;
     
    592595                          RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
    593596                          size_t cbWrite);
     597int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask);
    594598
    595599RT_C_DECLS_END
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