Changeset 23396 in vbox
- Timestamp:
- Sep 28, 2009 5:25:54 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52926
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
r23364 r23396 64 64 # define AIO_LISTIO_MAX UINT32_MAX 65 65 #endif 66 67 #if 0 /* Only used for debugging */ 68 # undef AIO_LISTIO_MAX 69 # define AIO_LISTIO_MAX 16 70 #endif 71 72 /** Invalid entry in the waiting array. */ 73 #define RTFILEAIOCTX_WAIT_ENTRY_INVALID (~0U) 66 74 67 75 /******************************************************************************* … … 128 136 * the operation. */ 129 137 RTSEMEVENT SemEventCancel; 130 /** Number of elements in the waiting list. */ 131 unsigned cReqsWait; 138 /** Head of submitted elements waiting to get into the array. */ 139 PRTFILEAIOREQINTERNAL pReqsWaitHead; 140 /** Tail of submitted elements waiting to get into the array. */ 141 PRTFILEAIOREQINTERNAL pReqsWaitTail; 142 /** Maximum number of elements in the waiting array. */ 143 unsigned cReqsWaitMax; 132 144 /** First free slot in the waiting list. */ 133 145 unsigned iFirstFree; 134 146 /** List of requests we are currently waiting on. 135 * Size depends on cMaxRequests . */147 * Size depends on cMaxRequests and AIO_LISTIO_MAX. */ 136 148 volatile PRTFILEAIOREQINTERNAL apReqs[1]; 137 149 } RTFILEAIOCTXINTERNAL, *PRTFILEAIOCTXINTERNAL; … … 188 200 NULL); 189 201 190 while (pReqHead) 202 while ( (pCtxInt->iFirstFree < pCtxInt->cReqsWaitMax) 203 && pReqHead) 191 204 { 192 205 pCtxInt->apReqs[pCtxInt->iFirstFree] = pReqHead; … … 198 211 pCtxInt->apReqs[pCtxInt->iFirstFree]->pPrev = NULL; 199 212 pCtxInt->iFirstFree++; 200 Assert(pCtxInt->iFirstFree <= pCtxInt->cMaxRequests); 213 214 Assert( (pCtxInt->iFirstFree <= pCtxInt->cMaxRequests) 215 && (pCtxInt->iFirstFree <= pCtxInt->cReqsWaitMax)); 216 } 217 218 /* Append the rest to the wait list. */ 219 if (pReqHead) 220 { 221 if (!pCtxInt->pReqsWaitHead) 222 { 223 Assert(!pCtxInt->pReqsWaitTail); 224 pCtxInt->pReqsWaitHead = pReqHead; 225 pReqHead->pPrev = NULL; 226 } 227 else 228 { 229 AssertPtr(pCtxInt->pReqsWaitTail); 230 231 pCtxInt->pReqsWaitTail->pNext = pReqHead; 232 pReqHead->pPrev = pCtxInt->pReqsWaitTail; 233 } 234 235 /* Update tail. */ 236 while (pReqHead->pNext) 237 pReqHead = pReqHead->pNext; 238 239 pCtxInt->pReqsWaitTail = pReqHead; 240 pCtxInt->pReqsWaitTail->pNext = NULL; 201 241 } 202 242 } … … 206 246 if (pReqToCancel) 207 247 { 208 /* Put it out of the waiting list. */ 209 pCtxInt->apReqs[pReqToCancel->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree]; 210 pCtxInt->apReqs[pReqToCancel->iWaitingList]->iWaitingList = pReqToCancel->iWaitingList; 248 /* The request can be in the array waiting for completion or still in the list because it is full. */ 249 if (pReqToCancel->iWaitingList != RTFILEAIOCTX_WAIT_ENTRY_INVALID) 250 { 251 /* Put it out of the waiting list. */ 252 pCtxInt->apReqs[pReqToCancel->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree]; 253 pCtxInt->apReqs[pReqToCancel->iWaitingList]->iWaitingList = pReqToCancel->iWaitingList; 254 } 255 else 256 { 257 /* Unlink from the waiting list. */ 258 PRTFILEAIOREQINTERNAL pPrev = pReqToCancel->pPrev; 259 PRTFILEAIOREQINTERNAL pNext = pReqToCancel->pNext; 260 261 if (pNext) 262 pNext->pPrev = pPrev; 263 else 264 { 265 /* We canceled the tail. */ 266 pCtxInt->pReqsWaitTail = pPrev; 267 } 268 269 if (pPrev) 270 pPrev->pNext = pNext; 271 else 272 { 273 /* We canceled the head. */ 274 pCtxInt->pReqsWaitHead = pNext; 275 } 276 } 277 211 278 ASMAtomicDecS32(&pCtxInt->cRequests); 212 279 RTSemEventSignal(pCtxInt->SemEventCancel); … … 282 349 return VERR_NO_MEMORY; 283 350 284 pReqInt->pCtxInt = NULL; 285 pReqInt->u32Magic = RTFILEAIOREQ_MAGIC; 351 pReqInt->pCtxInt = NULL; 352 pReqInt->u32Magic = RTFILEAIOREQ_MAGIC; 353 pReqInt->iWaitingList = RTFILEAIOCTX_WAIT_ENTRY_INVALID; 286 354 RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); 287 355 … … 447 515 { 448 516 PRTFILEAIOCTXINTERNAL pCtxInt; 517 unsigned cReqsWaitMax; 518 449 519 AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER); 450 520 … … 452 522 return VERR_OUT_OF_RANGE; 453 523 524 cReqsWaitMax = RT_MIN(cAioReqsMax, AIO_LISTIO_MAX); 525 454 526 pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ( sizeof(RTFILEAIOCTXINTERNAL) 455 + c AioReqsMax * sizeof(PRTFILEAIOREQINTERNAL));527 + cReqsWaitMax * sizeof(PRTFILEAIOREQINTERNAL)); 456 528 if (RT_UNLIKELY(!pCtxInt)) 457 529 return VERR_NO_MEMORY; … … 467 539 pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC; 468 540 pCtxInt->cMaxRequests = cAioReqsMax; 541 pCtxInt->cReqsWaitMax = cReqsWaitMax; 469 542 *phAioCtx = (RTFILEAIOCTX)pCtxInt; 470 543 … … 780 853 /* Requests finished. */ 781 854 unsigned iReqCurr = 0; 782 intcDone = 0;855 unsigned cDone = 0; 783 856 784 857 /* Remove completed requests from the waiting list. */ 785 while (iReqCurr < pCtxInt->iFirstFree) 858 while ( (iReqCurr < pCtxInt->iFirstFree) 859 && (cDone < cReqs)) 786 860 { 787 861 PRTFILEAIOREQINTERNAL pReq = pCtxInt->apReqs[iReqCurr]; … … 798 872 } 799 873 else 874 { 875 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) 876 pReq->Rc = RTErrConvertFromErrno(errno); 877 #else 800 878 pReq->Rc = RTErrConvertFromErrno(rcReq); 879 #endif 880 } 801 881 802 882 /* Mark the request as finished. */ … … 804 884 cDone++; 805 885 806 /* 807 * Move the last entry into the current position to avoid holes 808 * but only if it is not the last element already. 809 */ 810 if (pReq->iWaitingList < pCtxInt->iFirstFree - 1) 886 /* If there are other entries waiting put the head into the now free entry. */ 887 if (pCtxInt->pReqsWaitHead) 811 888 { 812 pCtxInt->apReqs[pReq->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree]; 813 pCtxInt->apReqs[pReq->iWaitingList]->iWaitingList = pReq->iWaitingList; 814 pCtxInt->apReqs[pCtxInt->iFirstFree] = NULL; 889 PRTFILEAIOREQINTERNAL pReqInsert = pCtxInt->pReqsWaitHead; 890 891 pCtxInt->pReqsWaitHead = pReqInsert->pNext; 892 if (!pCtxInt->pReqsWaitHead) 893 { 894 /* List is empty now. Clear tail too. */ 895 pCtxInt->pReqsWaitTail = NULL; 896 } 897 898 pReqInsert->iWaitingList = pReq->iWaitingList; 899 pCtxInt->apReqs[pReqInsert->iWaitingList] = pReqInsert; 900 iReqCurr++; 815 901 } 816 902 else 817 pCtxInt->iFirstFree--; 903 { 904 /* 905 * Move the last entry into the current position to avoid holes 906 * but only if it is not the last element already. 907 */ 908 if (pReq->iWaitingList < pCtxInt->iFirstFree - 1) 909 { 910 pCtxInt->apReqs[pReq->iWaitingList] = pCtxInt->apReqs[--pCtxInt->iFirstFree]; 911 pCtxInt->apReqs[pReq->iWaitingList]->iWaitingList = pReq->iWaitingList; 912 pCtxInt->apReqs[pCtxInt->iFirstFree] = NULL; 913 } 914 else 915 pCtxInt->iFirstFree--; 916 } 818 917 819 918 /* Put the request into the completed list. */ 820 919 pahReqs[cRequestsCompleted++] = pReq; 920 pReq->iWaitingList = RTFILEAIOCTX_WAIT_ENTRY_INVALID; 821 921 } 822 922 else … … 824 924 } 825 925 926 AssertMsg( (cDone <= cMinReqs) 927 && (cDone <= cReqs), ("Overflow cReqs=%u cMinReqs=%u cDone=%u\n", 928 cReqs, cMinReqs, cDone)); 826 929 cReqs -= cDone; 827 930 cMinReqs -= cDone;
Note:
See TracChangeset
for help on using the changeset viewer.