VirtualBox

Changeset 36799 in vbox


Ignore:
Timestamp:
Apr 21, 2011 4:48:42 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71355
Message:

AsyncCompletion: Add debugger command to inject delays. Disabled by default

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

Legend:

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

    r36285 r36799  
    7575#ifdef VBOX_WITH_DEBUGGER
    7676static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs);
     77static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs);
    7778#endif
    7879
     
    8990};
    9091
     92# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     93static const DBGCVARDESC g_aInjectDelayArgs[] =
     94{
     95    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     96    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "direction",    "write/read." },
     97    {  1,           1,          DBGCVAR_CAT_STRING,     0,                              "filename",     "Filename." },
     98    {  1,           1,          DBGCVAR_CAT_NUMBER,     0,                              "delay",        "Delay in milliseconds." },
     99};
     100# endif
     101
    91102/** Command descriptors. */
    92103static const DBGCCMD g_aCmds[] =
    93104{
    94105    /* pszCmd,       cArgsMin, cArgsMax, paArgDesc,                cArgDescs, fFlags, pfnHandler              pszSyntax, ....pszDescription */
    95     { "injecterror",        3, 3,        &g_aInjectErrorArgs[0],           3,      0, pdmacEpFileErrorInject, "",        "Inject error into I/O subsystem." },
     106    { "injecterror",        3, 3,        &g_aInjectErrorArgs[0],           3,      0, pdmacEpFileErrorInject, "",        "Inject error into I/O subsystem." }
     107# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     108    ,{ "injectdelay",        3, 3,        &g_aInjectDelayArgs[0],           3,      0, pdmacEpFileDelayInject, "",        "Inject a delay of a request." }
     109# endif
    96110};
    97111#endif
     
    351365        if (!(uOld - pTask->DataSeg.cbSeg)
    352366            && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
     367        {
     368#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     369            PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pTaskFile->Core.pEndpoint;
     370
     371            /* Check if we should delay completion of the request. */
     372            if (   ASMAtomicReadU32(&pEpFile->msDelay) > 0
     373                && ASMAtomicCmpXchgPtr(&pEpFile->pReqDelayed, pTaskFile, NULL))
     374            {
     375                /* Arm the delay. */
     376                pEpFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay;
     377                LogRel(("AIOMgr: Delaying request %#p for %u ms\n", pTaskFile, pEpFile->msDelay));
     378                return;
     379            }
     380#endif
    353381            pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
     382
     383#if PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     384            /* Check for an expired delay. */
     385            if (   pEpFile->pReqDelayed != NULL
     386                && RTTimeProgramMilliTS() >= pEpFile->tsDelayEnd)
     387            {
     388                pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pReqDelayed, NULL, PPDMASYNCCOMPLETIONTASKFILE);
     389                ASMAtomicXchgU32(&pEpFile->msDelay, 0);
     390                LogRel(("AIOMgr: Delayed request %#p completed\n", pTaskFile));
     391                pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
     392            }
     393#endif
     394        }
    354395    }
    355396}
     
    732773        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    733774    }
     775
    734776    if (pEpFile)
    735777    {
     
    752794    return VINF_SUCCESS;
    753795}
     796
     797# ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     798/**
     799 * Delay inject callback.
     800 */
     801static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs)
     802{
     803    /*
     804     * Validate input.
     805     */
     806    DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
     807    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
     808    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
     809    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
     810    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);
     811
     812    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
     813    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
     814
     815    /* Syntax is "read|write <filename> <status code>" */
     816    bool fWrite;
     817    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
     818        fWrite = false;
     819    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
     820        fWrite = true;
     821    else
     822        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);
     823
     824    uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number;
     825    if ((uint64_t)msDelay != pArgs[2].u.u64Number)
     826        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number);
     827
     828
     829    /*
     830     * Search for the matching endpoint.
     831     */
     832    RTCritSectEnter(&pEpClassFile->Core.CritSect);
     833
     834    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
     835    while (pEpFile)
     836    {
     837        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
     838            break;
     839        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
     840    }
     841
     842    if (pEpFile)
     843    {
     844        bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0);
     845
     846        if (fXchg)
     847            DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n",
     848                             msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString);
     849        else
     850            DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n",
     851                             pArgs[1].u.pszString);
     852    }
     853
     854    RTCritSectLeave(&pEpClassFile->Core.CritSect);
     855
     856    if (!pEpFile)
     857        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
     858    return VINF_SUCCESS;
     859}
     860# endif /* PDM_ASYNC_COMPLETION_FILE_WITH_DELAY */
     861
    754862#endif /* VBOX_WITH_DEBUGGER */
    755863
  • trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h

    r35346 r36799  
    4343 *  instead of managing larger blocks) to have this global for the whole VM.
    4444 */
     45
     46/** Enable for delay injection from the debugger. */
     47#if 0
     48# define PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     49#endif
    4550
    4651RT_C_DECLS_BEGIN
     
    366371    volatile int                           rcReqWrite;
    367372#endif
     373#ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY
     374    /** Request delay. */
     375    volatile uint32_t                      msDelay;
     376    /** The current task which gets delayed. */
     377    PPDMASYNCCOMPLETIONTASKFILE            pReqDelayed;
     378    /** Timestamp when the delay expires. */
     379    uint64_t                               tsDelayEnd;
     380#endif
    368381    /** Flag whether a blocking event is pending and needs
    369382     * processing by the I/O manager. */
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