VirtualBox

Changeset 43623 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Oct 11, 2012 8:33:20 PM (12 years ago)
Author:
vboxsync
Message:

AsyncCompletion/File: Use a timer to process delayed requests and introduce jitter parameter to the injectdelay debugger command

File:
1 edited

Legend:

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

    r41861 r43623  
    2929#include <VBox/dbg.h>
    3030#include <VBox/vmm/uvm.h>
     31#include <VBox/vmm/tm.h>
    3132
    3233#include <iprt/asm.h>
     
    4041#include <iprt/thread.h>
    4142#include <iprt/path.h>
     43#include <iprt/rand.h>
    4244
    4345#include "PDMAsyncCompletionFileInternal.h"
     
    7274    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "filename",     "Filename." },
    7375    {  1,           1,          DBGCVAR_CAT_NUMBER,     0,                              "delay",        "Delay in milliseconds." },
    74     {  1,           1,          DBGCVAR_CAT_NUMBER,     0,                              "reqs",         "Number of requests to delay." },
     76    {  1,           1,          DBGCVAR_CAT_NUMBER,     0,                              "jitter",       "Jitter of the delay." },
     77    {  1,           1,          DBGCVAR_CAT_NUMBER,     0,                              "reqs",         "Number of requests to delay." }
     78
    7579};
    7680# endif
     
    330334#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
    331335            PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pTaskFile->Core.pEndpoint;
     336            PPDMASYNCCOMPLETIONEPCLASSFILE  pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEpFile->Core.pEpClass;
    332337
    333338            /* Check if we should delay completion of the request. */
     
    335340                && ASMAtomicReadU32(&pEpFile->cReqsDelay) > 0)
    336341            {
     342                uint64_t tsDelay = (RTRandU32() % 100) > 50 ? pEpFile->msDelay + (RTRandU32() % pEpFile->msJitter)
     343                                                            : pEpFile->msDelay - (RTRandU32() % pEpFile->msJitter);
    337344                ASMAtomicDecU32(&pEpFile->cReqsDelay);
    338345
    339346                /* Arm the delay. */
    340                 pTaskFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay;
     347                pTaskFile->tsDelayEnd = RTTimeProgramMilliTS() + tsDelay;
    341348
    342349                /* Append to the list. */
     
    348355                } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTaskFile, pHead));
    349356
    350                 LogRel(("AIOMgr: Delaying request %#p for %u ms\n", pTaskFile, pEpFile->msDelay));
    351                 return;
     357                if (tsDelay < pEpClassFile->cMilliesNext)
     358                {
     359                    ASMAtomicWriteU64(&pEpClassFile->cMilliesNext, tsDelay);
     360                    TMTimerSetMillies(pEpClassFile->pTimer, tsDelay);
     361                }
     362
     363                LogRel(("AIOMgr: Delaying request %#p for %u ms\n", pTaskFile, tsDelay));
    352364            }
    353 #endif
    354             pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
    355 
    356 #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
    357             /* Check for an expired delay. */
    358             if (pEpFile->pDelayedHead != NULL)
    359             {
    360                 uint64_t tsCur = RTTimeProgramMilliTS();
    361                 pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pDelayedHead, NULL, PPDMASYNCCOMPLETIONTASKFILE);
    362 
    363                 while (pTaskFile)
    364                 {
    365                     PPDMASYNCCOMPLETIONTASKFILE pTmp = pTaskFile;
    366                     pTaskFile = pTaskFile->pDelayedNext;
    367 
    368                     if (tsCur >= pTmp->tsDelayEnd)
    369                     {
    370                         LogRel(("AIOMgr: Delayed request %#p completed\n", pTmp));
    371                         pdmR3AsyncCompletionCompleteTask(&pTmp->Core, pTmp->rc, true);
    372                     }
    373                     else
    374                     {
    375                         /* Prepend to the delayed list again. */
    376                         PPDMASYNCCOMPLETIONTASKFILE pHead = NULL;
    377                         do
    378                         {
    379                             pHead = ASMAtomicReadPtrT(&pEpFile->pDelayedHead, PPDMASYNCCOMPLETIONTASKFILE);
    380                             pTmp->pDelayedNext = pHead;
    381                         } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTmp, pHead));
    382                     }
    383                 }
    384             }
    385 #endif
     365            else
     366#endif
     367                pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
    386368        }
    387369    }
     
    726708
    727709    uint32_t cReqsDelay = 1;
     710    uint32_t msJitter = 0;
    728711    if (cArgs == 4)
    729         cReqsDelay = (uint32_t)pArgs[3].u.u64Number;
     712        msJitter = (uint32_t)pArgs[3].u.u64Number;
     713    if (cArgs == 5)
     714        cReqsDelay = (uint32_t)pArgs[4].u.u64Number;
    730715
    731716    /*
     
    746731        ASMAtomicWriteSize(&pEpFile->enmTypeDelay, enmDelayType);
    747732        ASMAtomicWriteU32(&pEpFile->msDelay, msDelay);
     733        ASMAtomicWriteU32(&pEpFile->msJitter, msJitter);
    748734        ASMAtomicWriteU32(&pEpFile->cReqsDelay, cReqsDelay);
    749735
     
    758744    return VINF_SUCCESS;
    759745}
     746
     747static DECLCALLBACK(void) pdmacR3TimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
     748{
     749    uint64_t tsCur = RTTimeProgramMilliTS();
     750    uint64_t cMilliesNext = UINT64_MAX;
     751    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pvUser;
     752
     753    ASMAtomicWriteU64(&pEpClassFile->cMilliesNext, UINT64_MAX);
     754
     755    /* Go through all endpoints and check for expired requests. */
     756    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
     757
     758    while (pEpFile)
     759    {
     760        /* Check for an expired delay. */
     761        if (pEpFile->pDelayedHead != NULL)
     762        {
     763            PPDMASYNCCOMPLETIONTASKFILE pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pDelayedHead, NULL, PPDMASYNCCOMPLETIONTASKFILE);
     764
     765            while (pTaskFile)
     766            {
     767                PPDMASYNCCOMPLETIONTASKFILE pTmp = pTaskFile;
     768                pTaskFile = pTaskFile->pDelayedNext;
     769
     770                if (tsCur >= pTmp->tsDelayEnd)
     771                {
     772                    LogRel(("AIOMgr: Delayed request %#p completed\n", pTmp));
     773                    pdmR3AsyncCompletionCompleteTask(&pTmp->Core, pTmp->rc, true);
     774                }
     775                else
     776                {
     777                    /* Prepend to the delayed list again. */
     778                    PPDMASYNCCOMPLETIONTASKFILE pHead = NULL;
     779
     780                    if (pTmp->tsDelayEnd - tsCur < cMilliesNext)
     781                        cMilliesNext = pTmp->tsDelayEnd - tsCur;
     782
     783                    do
     784                    {
     785                        pHead = ASMAtomicReadPtrT(&pEpFile->pDelayedHead, PPDMASYNCCOMPLETIONTASKFILE);
     786                        pTmp->pDelayedNext = pHead;
     787                    } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTmp, pHead));
     788                }
     789            }
     790        }
     791
     792        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
     793    }
     794
     795    if (cMilliesNext < pEpClassFile->cMilliesNext)
     796    {
     797        ASMAtomicWriteU64(&pEpClassFile->cMilliesNext, cMilliesNext);
     798        TMTimerSetMillies(pEpClassFile->pTimer, cMilliesNext);
     799    }
     800}
     801
    760802# endif /* PDM_ASYNC_COMPLETION_FILE_WITH_DELAY */
    761803
     
    836878        AssertRC(rc);
    837879    }
     880
     881#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     882    rc = TMR3TimerCreateInternal(pEpClassFile->Core.pVM, TMCLOCK_REAL, pdmacR3TimerCallback, pEpClassFile, "AC Delay", &pEpClassFile->pTimer);
     883    AssertRC(rc);
     884    pEpClassFile->cMilliesNext = UINT64_MAX;
     885#endif
    838886#endif
    839887
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