- Timestamp:
- Apr 25, 2010 8:48:36 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 60591
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h
r28317 r28719 126 126 */ 127 127 PDMACEPFILEMGRSTATE_SHUTDOWN, 128 /** The I/O manager waits for all active requests to complete and doesn't queue 129 * new ones because it needs to grow to handle more requests. 130 */ 131 PDMACEPFILEMGRSTATE_GROWING, 128 132 /** 32bit hack */ 129 133 PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff … … 163 167 /** Pointer to an array of free async I/O request handles. */ 164 168 RTFILEAIOREQ *pahReqsFree; 165 /** Next free position for a free request handle. */ 166 unsigned iFreeEntryNext; 167 /** Position of the next free task handle */ 168 unsigned iFreeReqNext; 169 /** Index of the next free entry in the cache. */ 170 uint32_t iFreeEntry; 169 171 /** Size of the array. */ 170 172 unsigned cReqEntries; -
trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
r28317 r28719 34 34 #define PDMACEPFILEMGR_LOAD_UPDATE_PERIOD 1000 35 35 /** Maximum number of requests a manager will handle. */ 36 #define PDMACEPFILEMGR_REQS_ MAX 512 /* @todo: Find better solution wrt. the request number*/36 #define PDMACEPFILEMGR_REQS_STEP 512 37 37 38 38 /******************************************************************************* … … 51 51 int rc = VINF_SUCCESS; 52 52 53 pAioMgr->cRequestsActiveMax = PDMACEPFILEMGR_REQS_ MAX;53 pAioMgr->cRequestsActiveMax = PDMACEPFILEMGR_REQS_STEP; 54 54 55 55 rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, RTFILEAIO_UNLIMITED_REQS); 56 56 if (rc == VERR_OUT_OF_RANGE) 57 rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, PDMACEPFILEMGR_REQS_MAX);57 rc = RTFileAioCtxCreate(&pAioMgr->hAioCtx, pAioMgr->cRequestsActiveMax); 58 58 59 59 if (RT_SUCCESS(rc)) 60 60 { 61 61 /* Initialize request handle array. */ 62 pAioMgr->iFreeEntryNext = 0; 63 pAioMgr->iFreeReqNext = 0; 64 pAioMgr->cReqEntries = pAioMgr->cRequestsActiveMax + 1; 62 pAioMgr->iFreeEntry = 0; 63 pAioMgr->cReqEntries = pAioMgr->cRequestsActiveMax; 65 64 pAioMgr->pahReqsFree = (RTFILEAIOREQ *)RTMemAllocZ(pAioMgr->cReqEntries * sizeof(RTFILEAIOREQ)); 66 65 … … 89 88 RTFileAioCtxDestroy(pAioMgr->hAioCtx); 90 89 91 while (pAioMgr->iFreeReqNext != pAioMgr->iFreeEntryNext) 92 { 93 RTFileAioReqDestroy(pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext]); 94 pAioMgr->iFreeReqNext = (pAioMgr->iFreeReqNext + 1) % pAioMgr->cReqEntries; 90 while (pAioMgr->iFreeEntry > 0) 91 { 92 pAioMgr->iFreeEntry--; 93 Assert(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] != NIL_RTFILEAIOREQ); 94 RTFileAioReqDestroy(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry]); 95 95 } 96 96 … … 316 316 317 317 /** 318 * Increase the maximum number of active requests for the given I/O manager. 319 * 320 * @returns VBox status code. 321 * @param pAioMgr The I/O manager to grow. 322 */ 323 static int pdmacFileAioMgrNormalGrow(PPDMACEPFILEMGR pAioMgr) 324 { 325 int rc = VINF_SUCCESS; 326 RTFILEAIOCTX hAioCtxNew = NIL_RTFILEAIOCTX; 327 328 LogFlowFunc(("pAioMgr=%#p\n", pAioMgr)); 329 330 AssertMsg( pAioMgr->enmState == PDMACEPFILEMGRSTATE_GROWING 331 && !pAioMgr->cRequestsActive, 332 ("Invalid state of the I/O manager\n")); 333 334 /* 335 * Reopen the files of all assigned endpoints first so we can assign them to the new 336 * I/O context. 337 */ 338 PPDMASYNCCOMPLETIONENDPOINTFILE pCurr = pAioMgr->pEndpointsHead; 339 340 while (pCurr) 341 { 342 RTFileClose(pCurr->File); 343 rc = RTFileOpen(&pCurr->File, pCurr->Core.pszUri, pCurr->fFlags); 344 AssertRC(rc); 345 346 pCurr = pCurr->AioMgr.pEndpointNext; 347 } 348 349 /* Create the new bigger context. */ 350 pAioMgr->cRequestsActiveMax += PDMACEPFILEMGR_REQS_STEP; 351 352 rc = RTFileAioCtxCreate(&hAioCtxNew, RTFILEAIO_UNLIMITED_REQS); 353 if (rc == VERR_OUT_OF_RANGE) 354 rc = RTFileAioCtxCreate(&hAioCtxNew, pAioMgr->cRequestsActiveMax); 355 356 if (RT_SUCCESS(rc)) 357 { 358 /* Close the old context. */ 359 rc = RTFileAioCtxDestroy(pAioMgr->hAioCtx); 360 AssertRC(rc); 361 362 pAioMgr->hAioCtx = hAioCtxNew; 363 364 /* Create a new I/O task handle array */ 365 uint32_t cReqEntriesNew = pAioMgr->cRequestsActiveMax + 1; 366 RTFILEAIOREQ *pahReqNew = (RTFILEAIOREQ *)RTMemAllocZ(cReqEntriesNew * sizeof(RTFILEAIOREQ)); 367 368 if (pahReqNew) 369 { 370 /* Copy the cached request handles. */ 371 for (uint32_t iReq = 0; iReq < pAioMgr->cReqEntries; iReq++) 372 pahReqNew[iReq] = pAioMgr->pahReqsFree[iReq]; 373 374 RTMemFree(pAioMgr->pahReqsFree); 375 pAioMgr->pahReqsFree = pahReqNew; 376 pAioMgr->cReqEntries = cReqEntriesNew; 377 LogFlowFunc(("I/O manager increased to handle a maximum of %u requests\n", 378 pAioMgr->cRequestsActiveMax)); 379 } 380 else 381 rc = VERR_NO_MEMORY; 382 } 383 384 /* Assign the file to the new context. */ 385 pCurr = pAioMgr->pEndpointsHead; 386 387 while (pCurr) 388 { 389 rc = RTFileAioCtxAssociateWithFile(pAioMgr->hAioCtx, pCurr->File); 390 AssertRC(rc); 391 392 pCurr = pCurr->AioMgr.pEndpointNext; 393 } 394 395 if (RT_FAILURE(rc)) 396 { 397 LogFlow(("Increasing size of the I/O manager failed with rc=%Rrc\n", rc)); 398 pAioMgr->cRequestsActiveMax -= PDMACEPFILEMGR_REQS_STEP; 399 } 400 401 pAioMgr->enmState = PDMACEPFILEMGRSTATE_RUNNING; 402 LogFlowFunc(("returns rc=%Rrc\n", rc)); 403 404 return rc; 405 } 406 407 /** 318 408 * Error handler which will create the failsafe managers and destroy the failed I/O manager. 319 409 * … … 383 473 384 474 /** 475 * Allocates a async I/O request. 476 * 477 * @returns Handle to the request. 478 * @param pAioMgr The I/O manager. 479 */ 480 static RTFILEAIOREQ pdmacFileAioMgrNormalRequestAlloc(PPDMACEPFILEMGR pAioMgr) 481 { 482 RTFILEAIOREQ hReq = NIL_RTFILEAIOREQ; 483 484 /* Get a request handle. */ 485 if (pAioMgr->iFreeEntry > 0) 486 { 487 pAioMgr->iFreeEntry--; 488 hReq = pAioMgr->pahReqsFree[pAioMgr->iFreeEntry]; 489 pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] = NIL_RTFILEAIOREQ; 490 Assert(hReq != NIL_RTFILEAIOREQ); 491 } 492 else 493 { 494 int rc = RTFileAioReqCreate(&hReq); 495 AssertRC(rc); 496 } 497 498 return hReq; 499 } 500 501 /** 502 * Frees a async I/O request handle. 503 * 504 * @returns nothing. 505 * @param pAioMgr The I/O manager. 506 * @param hReq The I/O request handle to free. 507 */ 508 static void pdmacFileAioMgrNormalRequestFree(PPDMACEPFILEMGR pAioMgr, RTFILEAIOREQ hReq) 509 { 510 Assert(pAioMgr->iFreeEntry < pAioMgr->cReqEntries); 511 Assert(pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] == NIL_RTFILEAIOREQ); 512 513 pAioMgr->pahReqsFree[pAioMgr->iFreeEntry] = hReq; 514 pAioMgr->iFreeEntry++; 515 } 516 517 /** 385 518 * Wrapper around RTFIleAioCtxSubmit() which is also doing error handling. 386 519 */ … … 428 561 PPDMACTASKFILE pTasksWaiting; 429 562 430 /* Put the entry on the free array */ 431 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = pahReqs[i]; 432 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries; 563 pdmacFileAioMgrNormalRequestFree(pAioMgr, pahReqs[i]); 433 564 434 565 if (pTask->cbBounceBuffer) … … 459 590 460 591 return rc; 461 }462 463 /**464 * Allocates a async I/O request.465 *466 * @returns Handle to the request.467 * @param pAioMgr The I/O manager.468 */469 static RTFILEAIOREQ pdmacFileAioMgrNormalRequestAlloc(PPDMACEPFILEMGR pAioMgr)470 {471 RTFILEAIOREQ hReq = NIL_RTFILEAIOREQ;472 473 /* Get a request handle. */474 if (pAioMgr->iFreeReqNext != pAioMgr->iFreeEntryNext)475 {476 hReq = pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext];477 pAioMgr->pahReqsFree[pAioMgr->iFreeReqNext] = NIL_RTFILEAIOREQ;478 pAioMgr->iFreeReqNext = (pAioMgr->iFreeReqNext + 1) % pAioMgr->cReqEntries;479 }480 else481 {482 int rc = RTFileAioReqCreate(&hReq);483 AssertRC(rc);484 }485 486 return hReq;487 592 } 488 593 … … 897 1002 && !pAioMgr->fBwLimitReached)) 898 1003 { 1004 #if 0 899 1005 /* 900 1006 * The I/O manager has no room left for more requests … … 903 1009 */ 904 1010 pdmacFileAioMgrNormalBalanceLoad(pAioMgr); 1011 #else 1012 /* Grow the I/O manager */ 1013 pAioMgr->enmState = PDMACEPFILEMGRSTATE_GROWING; 1014 #endif 905 1015 } 906 1016 } … … 1134 1244 { 1135 1245 /* Free bounce buffers and the IPRT request. */ 1136 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = hReq; 1137 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries; 1246 pdmacFileAioMgrNormalRequestFree(pAioMgr, hReq); 1138 1247 1139 1248 /* Free the lock and process pending tasks if neccessary */ … … 1229 1338 } 1230 1339 1231 /* Put the entry on the free array */ 1232 pAioMgr->pahReqsFree[pAioMgr->iFreeEntryNext] = hReq; 1233 pAioMgr->iFreeEntryNext = (pAioMgr->iFreeEntryNext + 1) % pAioMgr->cReqEntries; 1340 pdmacFileAioMgrNormalRequestFree(pAioMgr, hReq); 1234 1341 1235 1342 pAioMgr->cRequestsActive--; … … 1386 1493 1387 1494 /* Check endpoints for new requests. */ 1388 rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr); 1389 CHECK_RC(pAioMgr, rc); 1495 if (pAioMgr->enmState != PDMACEPFILEMGRSTATE_GROWING) 1496 { 1497 rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr); 1498 CHECK_RC(pAioMgr, rc); 1499 } 1390 1500 } /* while requests are active. */ 1501 1502 if (pAioMgr->enmState == PDMACEPFILEMGRSTATE_GROWING) 1503 { 1504 rc = pdmacFileAioMgrNormalGrow(pAioMgr); 1505 AssertRC(rc); 1506 Assert(pAioMgr->enmState == PDMACEPFILEMGRSTATE_RUNNING); 1507 } 1391 1508 } /* if still running */ 1392 1509 } /* while running */
Note:
See TracChangeset
for help on using the changeset viewer.