Changeset 82383 in vbox for trunk/src/VBox/Runtime/common/ioqueue
- Timestamp:
- Dec 4, 2019 1:19:31 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 135217
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/ioqueue/ioqueue-stdfile-provider.cpp
r79983 r82383 52 52 /** The waiting thread was interrupted by the external wakeup call. */ 53 53 #define RTIOQUEUE_STDFILE_PROV_STATE_F_EVTWAIT_INTR RT_BIT(1) 54 #define RTIOQUEUE_STDFILE_PROV_STATE_F_EVTWAIT_INTR_BIT 1 54 55 /** The I/O queue worker thread needs to be woken up to process new requests. */ 55 56 #define RTIOQUEUE_STDFILE_PROV_STATE_F_WORKER_NEED_WAKEUP RT_BIT(2) … … 109 110 /** Submission queue producer index. */ 110 111 volatile uint32_t idxSqProd; 112 /** Submission queue producer value for any uncommitted requests. */ 113 uint32_t idxSqProdUncommit; 111 114 /** Submission queue consumer index. */ 112 115 volatile uint32_t idxSqCons; … … 178 181 179 182 /* Write the result back into the completion queue. */ 180 pCqEntry->rcReq = rcReq; 181 pCqEntry->pvUser = pSqEntry->pvUser; 183 pCqEntry->rcReq = rcReq; 184 pCqEntry->pvUser = pSqEntry->pvUser; 185 pCqEntry->cbXfered = RT_SUCCESS(rcReq) ? pSqEntry->cbReq : 0; 182 186 } 183 187 … … 215 219 216 220 /* Process all requests. */ 221 uint32_t cCqFree = 0; 222 if (idxCqCons > pThis->idxCqProd) 223 cCqFree = pThis->cCqEntries - (pThis->cCqEntries - idxCqCons) - pThis->idxCqProd; 224 else 225 cCqFree = pThis->cCqEntries - pThis->idxCqProd - idxCqCons; 217 226 do 218 227 { 219 228 while ( idxSqCons != idxSqProd 220 && idxCqCons != pThis->idxCqProd)229 && cCqFree) 221 230 { 222 231 PCRTIOQUEUESSQENTRY pSqEntry = &pThis->paSqEntryBase[idxSqCons]; … … 227 236 228 237 idxSqCons = (idxSqCons + 1) % pThis->cSqEntries; 238 cCqFree--; 229 239 pThis->idxCqProd = (pThis->idxCqProd + 1) % pThis->cCqEntries; 240 ASMAtomicWriteU32(&pThis->idxSqCons, idxSqCons); 230 241 ASMWriteFence(); 231 242 if (ASMAtomicReadU32(&pThis->fState) & RTIOQUEUE_STDFILE_PROV_STATE_F_EVTWAIT_NEED_WAKEUP) … … 236 247 } 237 248 238 ASMWriteFence();239 ASMAtomicWriteU32(&pThis->idxSqCons, idxSqCons);240 249 idxSqProd = ASMAtomicReadU32(&pThis->idxSqProd); 241 idxSqCons = ASMAtomicReadU32(&pThis->idxSqCons);242 } while (idxSqCons != idxSqProd);250 } while ( idxSqCons != idxSqProd 251 && cCqFree); 243 252 } 244 253 … … 264 273 int rc = VINF_SUCCESS; 265 274 266 pThis->cSqEntries = cSqEntries; 267 pThis->cCqEntries = cCqEntries; 268 pThis->idxSqProd = 0; 269 pThis->idxSqCons = 0; 270 pThis->idxCqProd = 0; 271 pThis->idxCqCons = 0; 272 pThis->fShutdown = false; 273 pThis->fState = 0; 275 cSqEntries++; 276 cCqEntries++; 277 278 pThis->cSqEntries = cSqEntries; 279 pThis->cCqEntries = cCqEntries; 280 pThis->idxSqProd = 0; 281 pThis->idxSqProdUncommit = 0; 282 pThis->idxSqCons = 0; 283 pThis->idxCqProd = 0; 284 pThis->idxCqCons = 0; 285 pThis->fShutdown = false; 286 pThis->fState = 0; 274 287 275 288 pThis->paSqEntryBase = (PRTIOQUEUESSQENTRY)RTMemAllocZ(cSqEntries * sizeof(RTIOQUEUESSQENTRY)); … … 361 374 { 362 375 PRTIOQUEUEPROVINT pThis = hIoQueueProv; 363 uint32_t idxSqProd = ASMAtomicReadU32(&pThis->idxSqProd); 364 PRTIOQUEUESSQENTRY pSqEntry = &pThis->paSqEntryBase[idxSqProd]; 376 PRTIOQUEUESSQENTRY pSqEntry = &pThis->paSqEntryBase[pThis->idxSqProdUncommit]; 365 377 366 378 pSqEntry->hFile = pHandle->u.hFile; … … 372 384 pSqEntry->fSg = false; 373 385 pSqEntry->u.pvBuf = pvBuf; 374 ASMWriteFence(); 375 376 idxSqProd = (idxSqProd + 1) % pThis->cSqEntries; 377 ASMAtomicWriteU32(&pThis->idxSqProd, idxSqProd); 386 387 pThis->idxSqProdUncommit = (pThis->idxSqProdUncommit + 1) % pThis->cSqEntries; 378 388 return VINF_SUCCESS; 379 389 } … … 386 396 { 387 397 PRTIOQUEUEPROVINT pThis = hIoQueueProv; 388 uint32_t idxSqProd = ASMAtomicReadU32(&pThis->idxSqProd); 389 PRTIOQUEUESSQENTRY pSqEntry = &pThis->paSqEntryBase[idxSqProd]; 398 PRTIOQUEUESSQENTRY pSqEntry = &pThis->paSqEntryBase[pThis->idxSqProdUncommit]; 390 399 391 400 pSqEntry->hFile = pHandle->u.hFile; … … 397 406 pSqEntry->fSg = true; 398 407 pSqEntry->u.pSgBuf = pSgBuf; 399 ASMWriteFence(); 400 401 idxSqProd = (idxSqProd + 1) % pThis->cSqEntries; 402 ASMAtomicWriteU32(&pThis->idxSqProd, idxSqProd); 408 409 pThis->idxSqProdUncommit = (pThis->idxSqProdUncommit + 1) % pThis->cSqEntries; 403 410 return VINF_SUCCESS; 404 411 } … … 409 416 { 410 417 PRTIOQUEUEPROVINT pThis = hIoQueueProv; 411 RT_NOREF(pcReqsCommitted); 412 418 419 if (pThis->idxSqProd > pThis->idxSqProdUncommit) 420 *pcReqsCommitted = pThis->cSqEntries - pThis->idxSqProd + pThis->idxSqProdUncommit; 421 else 422 *pcReqsCommitted = pThis->idxSqProdUncommit - pThis->idxSqProd; 423 424 ASMWriteFence(); 425 ASMAtomicWriteU32(&pThis->idxSqProd, pThis->idxSqProdUncommit); 413 426 return RTSemEventSignal(pThis->hSemEvtWorker); 414 427 } … … 419 432 uint32_t cMinWait, uint32_t *pcCEvt, uint32_t fFlags) 420 433 { 421 PRTIOQUEUEPROVINT pThis = hIoQueueProv; 422 RT_NOREF(pThis, paCEvt, cCEvt, cMinWait, pcCEvt, fFlags); 423 424 return VERR_NOT_IMPLEMENTED; 434 RT_NOREF(fFlags); 435 436 PRTIOQUEUEPROVINT pThis = hIoQueueProv; 437 int rc = VINF_SUCCESS; 438 uint32_t idxCEvt = 0; 439 440 while ( RT_SUCCESS(rc) 441 && cMinWait 442 && cCEvt) 443 { 444 ASMAtomicOrU32(&pThis->fState, RTIOQUEUE_STDFILE_PROV_STATE_F_EVTWAIT_NEED_WAKEUP); 445 uint32_t idxCqProd = ASMAtomicReadU32(&pThis->idxCqProd); 446 uint32_t idxCqCons = ASMAtomicReadU32(&pThis->idxCqCons); 447 448 if (idxCqCons == idxCqProd) 449 { 450 rc = RTSemEventWait(pThis->hSemEvtWaitEvts, RT_INDEFINITE_WAIT); 451 AssertRC(rc); 452 if (ASMAtomicBitTestAndClear(&pThis->fState, RTIOQUEUE_STDFILE_PROV_STATE_F_EVTWAIT_INTR_BIT)) 453 { 454 rc = VERR_INTERRUPTED; 455 ASMAtomicBitTestAndClear(&pThis->fState, RTIOQUEUE_STDFILE_PROV_STATE_F_WORKER_NEED_WAKEUP_BIT); 456 break; 457 } 458 459 idxCqProd = ASMAtomicReadU32(&pThis->idxCqProd); 460 idxCqCons = ASMAtomicReadU32(&pThis->idxCqCons); 461 } 462 463 ASMAtomicBitTestAndClear(&pThis->fState, RTIOQUEUE_STDFILE_PROV_STATE_F_WORKER_NEED_WAKEUP_BIT); 464 465 /* Process all requests. */ 466 while ( idxCqCons != idxCqProd 467 && cCEvt) 468 { 469 PRTIOQUEUECEVT pCqEntry = &pThis->paCqEntryBase[idxCqCons]; 470 471 paCEvt[idxCEvt].rcReq = pCqEntry->rcReq; 472 paCEvt[idxCEvt].pvUser = pCqEntry->pvUser; 473 paCEvt[idxCEvt].cbXfered = pCqEntry->cbXfered; 474 ASMReadFence(); 475 476 idxCEvt++; 477 cCEvt--; 478 cMinWait--; 479 480 idxCqCons = (idxCqCons + 1) % pThis->cCqEntries; 481 pThis->idxCqCons = (pThis->idxCqCons + 1) % pThis->cCqEntries; 482 ASMWriteFence(); 483 } 484 } 485 486 *pcCEvt = idxCEvt; 487 return rc; 425 488 } 426 489
Note:
See TracChangeset
for help on using the changeset viewer.