- Timestamp:
- May 28, 2012 10:58:48 PM (13 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
r41434 r41469 44 44 #include "PDMAsyncCompletionFileInternal.h" 45 45 46 47 46 /******************************************************************************* 48 47 * Internal Functions * … … 71 70 { 72 71 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 73 { 1, 1, DBGCVAR_CAT_STRING, 0, "direction", "write /read." },72 { 1, 1, DBGCVAR_CAT_STRING, 0, "direction", "write|read|flush|any." }, 74 73 { 1, 1, DBGCVAR_CAT_STRING, 0, "filename", "Filename." }, 75 74 { 1, 1, DBGCVAR_CAT_NUMBER, 0, "delay", "Delay in milliseconds." }, 75 { 1, 1, DBGCVAR_CAT_NUMBER, 0, "reqs", "Number of requests to delay." }, 76 76 }; 77 77 # endif … … 83 83 { "injecterror", 3, 3, &g_aInjectErrorArgs[0], 3, 0, pdmacEpFileErrorInject, "", "Inject error into I/O subsystem." } 84 84 # ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY 85 ,{ "injectdelay", 3, 3, &g_aInjectDelayArgs[0], 3, 0, pdmacEpFileDelayInject, "", "Inject a delay of a request." }85 ,{ "injectdelay", 4, 4, &g_aInjectDelayArgs[0], 4, 0, pdmacEpFileDelayInject, "", "Inject a delay of a request." } 86 86 # endif 87 87 }; … … 334 334 /* Check if we should delay completion of the request. */ 335 335 if ( ASMAtomicReadU32(&pEpFile->msDelay) > 0 336 && ASMAtomic CmpXchgPtr(&pEpFile->pReqDelayed, pTaskFile, NULL))336 && ASMAtomicReadU32(&pEpFile->cReqsDelay) > 0) 337 337 { 338 ASMAtomicDecU32(&pEpFile->cReqsDelay); 339 338 340 /* Arm the delay. */ 339 pEpFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay; 341 pTaskFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay; 342 343 /* Append to the list. */ 344 PPDMASYNCCOMPLETIONTASKFILE pHead = NULL; 345 do 346 { 347 pHead = ASMAtomicReadPtrT(&pEpFile->pDelayedHead, PPDMASYNCCOMPLETIONTASKFILE); 348 pTaskFile->pDelayedNext = pHead; 349 } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTaskFile, pHead)); 350 340 351 LogRel(("AIOMgr: Delaying request %#p for %u ms\n", pTaskFile, pEpFile->msDelay)); 341 352 return; … … 344 355 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true); 345 356 346 #if PDM_ASYNC_COMPLETION_FILE_WITH_DELAY357 #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY 347 358 /* Check for an expired delay. */ 348 if ( pEpFile->pReqDelayed != NULL 349 && RTTimeProgramMilliTS() >= pEpFile->tsDelayEnd) 359 if (pEpFile->pDelayedHead != NULL) 350 360 { 351 pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pReqDelayed, NULL, PPDMASYNCCOMPLETIONTASKFILE); 352 ASMAtomicXchgU32(&pEpFile->msDelay, 0); 353 LogRel(("AIOMgr: Delayed request %#p completed\n", pTaskFile)); 354 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true); 361 uint64_t tsCur = RTTimeProgramMilliTS(); 362 pTaskFile = ASMAtomicXchgPtrT(&pEpFile->pDelayedHead, NULL, PPDMASYNCCOMPLETIONTASKFILE); 363 364 while (pTaskFile) 365 { 366 PPDMASYNCCOMPLETIONTASKFILE pTmp = pTaskFile; 367 pTaskFile = pTaskFile->pDelayedNext; 368 369 if (tsCur >= pTmp->tsDelayEnd) 370 { 371 LogRel(("AIOMgr: Delayed request %#p completed\n", pTmp)); 372 pdmR3AsyncCompletionCompleteTask(&pTmp->Core, pTmp->rc, true); 373 } 374 else 375 { 376 /* Prepend to the delayed list again. */ 377 PPDMASYNCCOMPLETIONTASKFILE pHead = NULL; 378 do 379 { 380 pHead = ASMAtomicReadPtrT(&pEpFile->pDelayedHead, PPDMASYNCCOMPLETIONTASKFILE); 381 pTmp->pDelayedNext = pHead; 382 } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTmp, pHead)); 383 } 384 } 355 385 } 356 386 #endif … … 671 701 */ 672 702 DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM); 673 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);703 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs >= 3); 674 704 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING); 675 705 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING); … … 679 709 pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE]; 680 710 681 /* Syntax is "read|write <filename> <status code>" */682 bool fWrite;711 /* Syntax is "read|write|flush|any <filename> <delay> [reqs]" */ 712 PDMACFILEREQTYPEDELAY enmDelayType = PDMACFILEREQTYPEDELAY_ANY; 683 713 if (!RTStrCmp(pArgs[0].u.pszString, "read")) 684 fWrite = false;714 enmDelayType = PDMACFILEREQTYPEDELAY_READ; 685 715 else if (!RTStrCmp(pArgs[0].u.pszString, "write")) 686 fWrite = true; 716 enmDelayType = PDMACFILEREQTYPEDELAY_WRITE; 717 else if (!RTStrCmp(pArgs[0].u.pszString, "flush")) 718 enmDelayType = PDMACFILEREQTYPEDELAY_FLUSH; 719 else if (!RTStrCmp(pArgs[0].u.pszString, "any")) 720 enmDelayType = PDMACFILEREQTYPEDELAY_ANY; 687 721 else 688 722 return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString); … … 692 726 return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number); 693 727 728 uint32_t cReqsDelay = 1; 729 if (cArgs == 4) 730 cReqsDelay = (uint32_t)pArgs[3].u.u64Number; 694 731 695 732 /* … … 708 745 if (pEpFile) 709 746 { 710 bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0); 711 712 if (fXchg) 713 DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n", 714 msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString); 715 else 716 DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n", 717 pArgs[1].u.pszString); 747 ASMAtomicWriteSize(&pEpFile->enmTypeDelay, enmDelayType); 748 ASMAtomicWriteU32(&pEpFile->msDelay, msDelay); 749 ASMAtomicWriteU32(&pEpFile->cReqsDelay, cReqsDelay); 750 751 DBGCCmdHlpPrintf(pCmdHlp, "Injected delay for the next %u requests of %u ms into '%s' for %s\n", 752 cReqsDelay, msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString); 718 753 } 719 754 -
trunk/src/VBox/VMM/include/PDMAsyncCompletionFileInternal.h
r39078 r41469 311 311 } PDMASYNCCOMPLETIONENDPOINTFILESTATE; 312 312 313 typedef enum PDMACFILEREQTYPEDELAY 314 { 315 PDMACFILEREQTYPEDELAY_ANY = 0, 316 PDMACFILEREQTYPEDELAY_READ, 317 PDMACFILEREQTYPEDELAY_WRITE, 318 PDMACFILEREQTYPEDELAY_FLUSH, 319 PDMACFILEREQTYPEDELAY_32BIT_HACK = 0x7fffffff 320 } PDMACFILEREQTYPEDELAY; 321 313 322 /** 314 323 * Data for the file endpoint. … … 371 380 /** Request delay. */ 372 381 volatile uint32_t msDelay; 382 /** Number of requests to delay. */ 383 volatile uint32_t cReqsDelay; 384 /** Task type to delay. */ 385 PDMACFILEREQTYPEDELAY enmTypeDelay; 373 386 /** The current task which gets delayed. */ 374 PPDMASYNCCOMPLETIONTASKFILE pReqDelayed; 375 /** Timestamp when the delay expires. */ 376 uint64_t tsDelayEnd; 387 PPDMASYNCCOMPLETIONTASKFILE pDelayedHead; 377 388 #endif 378 389 /** Flag whether a blocking event is pending and needs … … 498 509 /** Return code. */ 499 510 volatile int rc; 511 #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY 512 volatile PPDMASYNCCOMPLETIONTASKFILE pDelayedNext; 513 /** Timestamp when the delay expires. */ 514 uint64_t tsDelayEnd; 515 #endif 500 516 } PDMASYNCCOMPLETIONTASKFILE; 501 517
Note:
See TracChangeset
for help on using the changeset viewer.