Changeset 43623 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Oct 11, 2012 8:33:20 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
r41861 r43623 29 29 #include <VBox/dbg.h> 30 30 #include <VBox/vmm/uvm.h> 31 #include <VBox/vmm/tm.h> 31 32 32 33 #include <iprt/asm.h> … … 40 41 #include <iprt/thread.h> 41 42 #include <iprt/path.h> 43 #include <iprt/rand.h> 42 44 43 45 #include "PDMAsyncCompletionFileInternal.h" … … 72 74 { 1, 1, DBGCVAR_CAT_STRING, 0, "filename", "Filename." }, 73 75 { 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 75 79 }; 76 80 # endif … … 330 334 #ifdef PDM_ASYNC_COMPLETION_FILE_WITH_DELAY 331 335 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pTaskFile->Core.pEndpoint; 336 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEpFile->Core.pEpClass; 332 337 333 338 /* Check if we should delay completion of the request. */ … … 335 340 && ASMAtomicReadU32(&pEpFile->cReqsDelay) > 0) 336 341 { 342 uint64_t tsDelay = (RTRandU32() % 100) > 50 ? pEpFile->msDelay + (RTRandU32() % pEpFile->msJitter) 343 : pEpFile->msDelay - (RTRandU32() % pEpFile->msJitter); 337 344 ASMAtomicDecU32(&pEpFile->cReqsDelay); 338 345 339 346 /* Arm the delay. */ 340 pTaskFile->tsDelayEnd = RTTimeProgramMilliTS() + pEpFile->msDelay;347 pTaskFile->tsDelayEnd = RTTimeProgramMilliTS() + tsDelay; 341 348 342 349 /* Append to the list. */ … … 348 355 } while (!ASMAtomicCmpXchgPtr(&pEpFile->pDelayedHead, pTaskFile, pHead)); 349 356 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)); 352 364 } 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); 386 368 } 387 369 } … … 726 708 727 709 uint32_t cReqsDelay = 1; 710 uint32_t msJitter = 0; 728 711 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; 730 715 731 716 /* … … 746 731 ASMAtomicWriteSize(&pEpFile->enmTypeDelay, enmDelayType); 747 732 ASMAtomicWriteU32(&pEpFile->msDelay, msDelay); 733 ASMAtomicWriteU32(&pEpFile->msJitter, msJitter); 748 734 ASMAtomicWriteU32(&pEpFile->cReqsDelay, cReqsDelay); 749 735 … … 758 744 return VINF_SUCCESS; 759 745 } 746 747 static 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 760 802 # endif /* PDM_ASYNC_COMPLETION_FILE_WITH_DELAY */ 761 803 … … 836 878 AssertRC(rc); 837 879 } 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 838 886 #endif 839 887
Note:
See TracChangeset
for help on using the changeset viewer.