Changeset 22851 in vbox
- Timestamp:
- Sep 8, 2009 11:38:47 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp
r22757 r22851 723 723 PPDMACFILECACHEENTRY pEntry = (PPDMACFILECACHEENTRY)pNode; 724 724 PPDMACFILECACHEGLOBAL pCache = (PPDMACFILECACHEGLOBAL)pvUser; 725 PPDMACFILEENDPOINTCACHE pEndpointCache = &pEntry->pEndpoint->DataCache; 726 727 while (pEntry->fFlags & (PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)) 728 { 729 RTSemRWReleaseWrite(pEndpointCache->SemRWEntries); 730 RTThreadSleep(250); 731 RTSemRWRequestWrite(pEndpointCache->SemRWEntries, RT_INDEFINITE_WAIT); 732 } 725 733 726 734 AssertMsg(!(pEntry->fFlags & (PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)), -
trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h
r22757 r22851 497 497 /** Pointer to the used bounce buffer if any. */ 498 498 void *pvBounceBuffer; 499 /** Start offset in the bounce buffer to copy from. */ 500 uint32_t uBounceBufOffset; 501 /** Flag whether this is a prefetch request. */ 502 bool fPrefetch; 499 503 /** Completion function to call on completion. */ 500 504 PFNPDMACTASKCOMPLETED pfnCompleted; -
trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
r22757 r22851 368 368 AssertMsg(hReq != NIL_RTFILEAIOREQ, ("Out of request handles\n")); 369 369 370 /* Check if the alignment requirements are met. */ 371 if ((pEpClassFile->uBitmaskAlignment & (RTR3UINTPTR)pvBuf) != (RTR3UINTPTR)pvBuf) 370 /* Check if the alignment requirements are met. 371 * Offset, transfer size and buffer address 372 * need to be on a 512 boundary. */ 373 size_t cbToTransfer = RT_ALIGN_Z(pCurr->DataSeg.cbSeg, 512); 374 RTFOFF OffStart = pCurr->Off & ~(RTFOFF)(512-1); 375 PDMACTASKFILETRANSFER enmTransferType = pCurr->enmTransferType; 376 377 AssertMsg(( (pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE) 378 || (OffStart + cbToTransfer <= pEndpoint->cbFile)), 379 ("Read exceeds file size OffStart=%RTfoff cbToTransfer=%d cbFile=%llu\n", 380 OffStart, cbToTransfer, pEndpoint->cbFile)); 381 382 pCurr->fPrefetch = false; 383 384 if ( RT_UNLIKELY(cbToTransfer != pCurr->DataSeg.cbSeg) 385 || RT_UNLIKELY(OffStart != pCurr->Off) 386 || ((pEpClassFile->uBitmaskAlignment & (RTR3UINTPTR)pvBuf) != (RTR3UINTPTR)pvBuf)) 372 387 { 373 388 /* Create bounce buffer. */ 374 389 pCurr->fBounceBuffer = true; 390 391 AssertMsg(pCurr->Off >= OffStart, ("Overflow in calculation Off=%llu OffStart=%llu\n", 392 pCurr->Off, OffStart)); 393 pCurr->uBounceBufOffset = pCurr->Off - OffStart; 375 394 376 395 /** @todo: I think we need something like a RTMemAllocAligned method here. … … 379 398 * so we can use RTMemPageAlloc here. 380 399 */ 381 pCurr->pvBounceBuffer = RTMemPageAlloc( pCurr->DataSeg.cbSeg);400 pCurr->pvBounceBuffer = RTMemPageAlloc(cbToTransfer); 382 401 AssertPtr(pCurr->pvBounceBuffer); 383 402 pvBuf = pCurr->pvBounceBuffer; 384 403 385 404 if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE) 386 memcpy(pvBuf, pCurr->DataSeg.pvSeg, pCurr->DataSeg.cbSeg); 405 { 406 if ( RT_UNLIKELY(cbToTransfer != pCurr->DataSeg.cbSeg) 407 || RT_UNLIKELY(OffStart != pCurr->Off)) 408 { 409 /* We have to fill the buffer first before we can update the data. */ 410 pCurr->fPrefetch = true; 411 enmTransferType = PDMACTASKFILETRANSFER_READ; 412 } 413 else 414 memcpy(pvBuf, pCurr->DataSeg.pvSeg, pCurr->DataSeg.cbSeg); 415 } 387 416 } 388 417 else … … 392 421 ("AIO: Alignment restrictions not met!\n")); 393 422 394 if ( pCurr->enmTransferType == PDMACTASKFILETRANSFER_WRITE)423 if (enmTransferType == PDMACTASKFILETRANSFER_WRITE) 395 424 { 396 425 /* Grow the file if needed. */ … … 402 431 403 432 rc = RTFileAioReqPrepareWrite(hReq, pEndpoint->File, 404 pCurr->Off, pvBuf, pCurr->DataSeg.cbSeg, pCurr);433 OffStart, pvBuf, cbToTransfer, pCurr); 405 434 } 406 435 else 407 436 rc = RTFileAioReqPrepareRead(hReq, pEndpoint->File, 408 pCurr->Off, pvBuf, pCurr->DataSeg.cbSeg, pCurr);437 OffStart, pvBuf, cbToTransfer, pCurr); 409 438 AssertRC(rc); 410 439 … … 687 716 688 717 AssertMsg( RT_SUCCESS(rcReq) 689 && (cbTransfered == pTask->DataSeg.cbSeg), 718 && ( (cbTransfered == pTask->DataSeg.cbSeg) 719 || (pTask->fBounceBuffer)), 690 720 ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rc, cbTransfered)); 691 721 692 if (pTask->fBounceBuffer) 693 { 694 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ) 695 memcpy(pTask->DataSeg.pvSeg, pTask->pvBounceBuffer, pTask->DataSeg.cbSeg); 696 697 RTMemPageFree(pTask->pvBounceBuffer); 698 } 699 700 /* Put the entry on the free array */ 701 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = apReqs[i]; 702 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) %pAioMgr->cReqEntries; 703 704 pAioMgr->cRequestsActive--; 705 pEndpoint->AioMgr.cReqsProcessed++; 706 707 /* Call completion callback */ 708 pTask->pfnCompleted(pTask, pTask->pvUser); 709 pdmacFileTaskFree(pEndpoint, pTask); 710 711 /* 712 * If there is no request left on the endpoint but a flush request is set 713 * it completed now and we notify the owner. 714 * Furthermore we look for new requests and continue. 715 */ 716 if (!pEndpoint->AioMgr.cRequestsActive && pEndpoint->pFlushReq) 717 { 722 if (pTask->fPrefetch) 723 { 724 Assert(pTask->enmTransferType == PDMACTASKFILETRANSFER_WRITE); 725 Assert(pTask->fBounceBuffer); 726 727 memcpy(((uint8_t *)pTask->pvBounceBuffer) + pTask->uBounceBufOffset, 728 pTask->DataSeg.pvSeg, 729 pTask->DataSeg.cbSeg); 730 731 /* Write it now. */ 732 pTask->fPrefetch = false; 733 size_t cbToTransfer = RT_ALIGN_Z(pTask->DataSeg.cbSeg, 512); 734 RTFOFF OffStart = pTask->Off & ~(RTFOFF)(512-1); 735 736 /* Grow the file if needed. */ 737 if (RT_UNLIKELY((pTask->Off + pTask->DataSeg.cbSeg) > pEndpoint->cbFile)) 738 { 739 ASMAtomicWriteU64(&pEndpoint->cbFile, pTask->Off + pTask->DataSeg.cbSeg); 740 RTFileSetSize(pEndpoint->File, pTask->Off + pTask->DataSeg.cbSeg); 741 } 742 743 rc = RTFileAioReqPrepareWrite(apReqs[i], pEndpoint->File, 744 OffStart, pTask->pvBounceBuffer, cbToTransfer, pTask); 745 AssertRC(rc); 746 rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, &apReqs[i], 1); 747 AssertRC(rc); 748 } 749 else 750 { 751 if (pTask->fBounceBuffer) 752 { 753 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ) 754 memcpy(pTask->DataSeg.pvSeg, 755 ((uint8_t *)pTask->pvBounceBuffer) + pTask->uBounceBufOffset, 756 pTask->DataSeg.cbSeg); 757 758 RTMemPageFree(pTask->pvBounceBuffer); 759 } 760 761 /* Put the entry on the free array */ 762 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = apReqs[i]; 763 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) %pAioMgr->cReqEntries; 764 765 pAioMgr->cRequestsActive--; 766 pEndpoint->AioMgr.cReqsProcessed++; 767 718 768 /* Call completion callback */ 719 pTask = pEndpoint->pFlushReq;720 pEndpoint->pFlushReq = NULL;721 722 AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n"));723 724 769 pTask->pfnCompleted(pTask, pTask->pvUser); 725 770 pdmacFileTaskFree(pEndpoint, pTask); 771 772 /* 773 * If there is no request left on the endpoint but a flush request is set 774 * it completed now and we notify the owner. 775 * Furthermore we look for new requests and continue. 776 */ 777 if (!pEndpoint->AioMgr.cRequestsActive && pEndpoint->pFlushReq) 778 { 779 /* Call completion callback */ 780 pTask = pEndpoint->pFlushReq; 781 pEndpoint->pFlushReq = NULL; 782 783 AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n")); 784 785 pTask->pfnCompleted(pTask, pTask->pvUser); 786 pdmacFileTaskFree(pEndpoint, pTask); 787 } 726 788 } 727 789
Note:
See TracChangeset
for help on using the changeset viewer.