Changeset 19185 in vbox
- Timestamp:
- Apr 26, 2009 9:04:33 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/file.h
r19125 r19185 787 787 * RTFileAioReqPrepareWrite() which will write to a given file. 788 788 * 789 * The second object is the context. Requests are associated with a context 790 * during RTFileAioCtxSubmit() which will also submit the requests to the 791 * operating system. 789 * The second object is the context. A file is associated with a context 790 * and requests for this file may complete only on the context the file 791 * was associated with and not on the context given in RTFileAioCtxSubmit() 792 * (see below for further information). 792 793 * RTFileAioCtxWait() is used to wait for completion of requests which were 793 794 * associated with the context. While waiting for requests the thread can not … … 811 812 * there are some things to consider to make the code as portable as possible. 812 813 * 813 * The onlyrestriction at the moment is that every buffer has to be aligned to a 512 byte boundary.814 * The first restriction at the moment is that every buffer has to be aligned to a 512 byte boundary. 814 815 * This limitation comes from the Linux io_* interface. To use the interface the file 815 816 * must be opened with O_DIRECT. This flag disables the kernel cache too which may … … 822 823 * file systems. So Linus comment about this flag is comprehensible but Linux 823 824 * lacks an alternative at the moment. 825 * 826 * The next limitation applies only to Windows. Reqeusts are not assoicated with the 827 * I/O context they are associated with but with the file the request is for. 828 * The file needs to be associated with exactly one I/O completion port and requests 829 * for this file will only arrive at that context after they completed and not on 830 * the context the request was submitted. 831 * To associate a file with a specific context RTFileAioCtxAssociateWithFile() is 832 * used. It is only implemented on Windows and does nothing on the other platforms. 833 * If the file needs to be associated with different context for some reason 834 * the file must be closed first. After it was opened again the new context 835 * can be associated with the other context. 836 * This can't be done by the API because there is no way to retrieve the flags 837 * the file was opened with. 824 838 */ 825 839 … … 963 977 964 978 /** 979 * Associates a file with a async I/O context. 980 * Requests for this file will arrive at the completion port 981 * associated with the file. 982 * 983 * @returns IPRT status code. 984 * 985 * @param hAioCtx The async I/O context handle. 986 * @param hFile The file handle. 987 */ 988 RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile); 989 990 /** 965 991 * Submits a set of requests to an async I/O context for processing. 966 *967 * @todo Is it possible to call this API while another thread is in968 * RTFileAioCtxWait?969 992 * 970 993 * @returns IPRT status code. … … 973 996 * @param pahReqs Pointer to an array of request handles. 974 997 * @param cReqs The number of entries in the array. 998 * @param pcReqs Where to store the number of requests 999 * successfully submitted before an error 1000 * occured. If VINF_SUCCESS is returned 1001 * the value equals cReqs. This value is always 1002 * set. 975 1003 * 976 1004 * @remarks @a cReqs uses the type size_t while it really is a uint32_t, this is … … 978 1006 * macros. 979 1007 */ 980 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ p hReqs, size_tcReqs);1008 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs, size_t *pcReqs); 981 1009 982 1010 /** -
trunk/src/VBox/Runtime/r3/linux/fileaio-linux.cpp
r19126 r19185 458 458 *phAioCtx = (RTFILEAIOCTX)pCtxInt; 459 459 } 460 else 461 RTMemFree(pCtxInt); 460 462 461 463 return rc; … … 500 502 } 501 503 502 503 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs) 504 RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTS hAioCtx, RTFILE hFile) 505 { 506 /* Nothing to do. */ 507 return VINF_SUCCESS; 508 } 509 510 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs, size_t *pcReqs) 504 511 { 505 512 /* 506 513 * Parameter validation. 507 514 */ 515 AssertPtrReturn(pcReqs, VERR_INVALID_POINTER); 516 *pcReqs = 0; 508 517 PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx; 509 518 RTFILEAIOCTX_VALID_RETURN(pCtxInt); … … 539 548 if (RT_FAILURE(rc)) 540 549 ASMAtomicSubS32(&pCtxInt->cRequests, cReqs); 550 else 551 *pcReqs = cReqs; 541 552 542 553 return rc; -
trunk/src/VBox/Runtime/testcase/tstFileAio.cpp
r19054 r19185 63 63 RTFOFF Offset = 0; 64 64 size_t cbLeft = cbTestFile; 65 66 /* Initialize buffers. */ 67 for (unsigned i = 0; i < RT_ELEMENTS(apvBuf); i++) 65 int cRun = 0; 66 67 /* Associate file with context.*/ 68 rc = RTFileAioCtxAssociateWithFile(hAioContext, File); 69 if (RT_SUCCESS(rc)) 68 70 { 69 apvBuf[i] = RTMemPageAllocZ(cbTestBuf); 70 71 if (fWrite) 72 memcpy(apvBuf[i], pvTestBuf, cbTestBuf); 71 /* Initialize buffers. */ 72 for (unsigned i = 0; i < RT_ELEMENTS(apvBuf); i++) 73 { 74 apvBuf[i] = RTMemPageAllocZ(cbTestBuf); 75 76 if (fWrite) 77 memcpy(apvBuf[i], pvTestBuf, cbTestBuf); 78 } 79 80 /* Initialize requests. */ 81 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++) 82 RTFileAioReqCreate(&aReqs[i]); 83 84 while (cbLeft) 85 { 86 int cReqs = 0; 87 size_t cReqsSubmitted = 0; 88 89 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++) 90 { 91 size_t cbTransfer = (cbLeft < cbTestBuf) ? cbLeft : cbTestBuf; 92 93 if (!cbTransfer) 94 break; 95 96 if (fWrite) 97 rc = RTFileAioReqPrepareWrite(aReqs[i], File, Offset, apvBuf[i], 98 cbTransfer, apvBuf[i]); 99 else 100 rc = RTFileAioReqPrepareRead(aReqs[i], File, Offset, apvBuf[i], 101 cbTransfer, apvBuf[i]); 102 103 cbLeft -= cbTransfer; 104 Offset += cbTransfer; 105 cReqs++; 106 } 107 108 rc = RTFileAioCtxSubmit(hAioContext, aReqs, cReqs, &cReqsSubmitted); 109 if (RT_FAILURE(rc)) 110 { 111 RTPrintf("tstFileAio: FATAL ERROR - Failed to submit tasks after %d runs. rc=%Rrc\n", cRun, rc); 112 cErrors++; 113 break; 114 } 115 else if (cReqs != cReqsSubmitted) 116 { 117 RTPrintf("tstFileAio: FATAL ERROR - Submitted tasks but the result is not equal to the number of submitted tasks\n", rc); 118 cErrors++; 119 break; 120 } 121 122 /* Wait */ 123 RTFILEAIOREQ aReqsCompleted[TSTFILEAIO_MAX_REQS_IN_FLIGHT]; 124 uint32_t cCompleted = 0; 125 rc = RTFileAioCtxWait(hAioContext, cReqs, RT_INDEFINITE_WAIT, 126 aReqsCompleted, TSTFILEAIO_MAX_REQS_IN_FLIGHT, 127 &cCompleted); 128 if (RT_FAILURE(rc)) 129 { 130 RTPrintf("tstFileAio: FATAL ERROR - Waiting failed. rc=%Rrc\n", rc); 131 cErrors++; 132 break; 133 } 134 135 if (!fWrite) 136 { 137 for (uint32_t i = 0; i < cCompleted; i++) 138 { 139 /* Compare that we read the right stuff. */ 140 void *pvBuf = RTFileAioReqGetUser(aReqsCompleted[i]); 141 142 size_t cbTransfered; 143 int rcReq = RTFileAioReqGetRC(aReqsCompleted[i], &cbTransfered); 144 if (RT_FAILURE(rcReq) || (cbTransfered != cbTestBuf)) 145 { 146 RTPrintf("tstFileAio: FATAL ERROR - Request %d failed with rc=%Rrc cbTransfered=%d.\n", 147 i, rcReq, cbTransfered); 148 cErrors++; 149 rc = rcReq; 150 break; 151 } 152 153 if (memcmp(pvBuf, pvTestBuf, cbTestBuf) != 0) 154 { 155 RTPrintf("tstFileAio: FATAL ERROR - Unexpected content in memory.\n"); 156 cErrors++; 157 break; 158 } 159 memset(pvBuf, 0, cbTestBuf); 160 } 161 } 162 cRun++; 163 if (RT_FAILURE(rc)) 164 break; 165 } 166 167 /* Free buffers. */ 168 for (unsigned i = 0; i < RT_ELEMENTS(apvBuf); i++) 169 RTMemPageFree(apvBuf[i]); 170 171 /* Free requests. */ 172 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++) 173 RTFileAioReqDestroy(aReqs[i]); 174 175 NanoTS = RTTimeNanoTS() - NanoTS; 176 unsigned SpeedKBs = cbTestFile / (NanoTS / 1000000000.0) / 1024; 177 178 RTPrintf("tstFileAio: Completed simple %s test: %d.%03d MB/sec\n", 179 fWrite ? "write" : "read", 180 SpeedKBs / 1000, 181 SpeedKBs % 1000); 73 182 } 74 75 /* Initialize requests. */ 76 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++) 77 RTFileAioReqCreate(&aReqs[i]); 78 79 while (cbLeft) 183 else 80 184 { 81 int cReqs = 0; 82 83 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++) 84 { 85 size_t cbTransfer = (cbLeft < cbTestBuf) ? cbLeft : cbTestBuf; 86 87 if (!cbTransfer) 88 break; 89 90 if (fWrite) 91 rc = RTFileAioReqPrepareWrite(aReqs[i], File, Offset, apvBuf[i], 92 cbTransfer, apvBuf[i]); 93 else 94 rc = RTFileAioReqPrepareRead(aReqs[i], File, Offset, apvBuf[i], 95 cbTransfer, apvBuf[i]); 96 97 cbLeft -= cbTransfer; 98 Offset += cbTransfer; 99 cReqs++; 100 } 101 102 rc = RTFileAioCtxSubmit(hAioContext, aReqs, cReqs); 103 if (RT_FAILURE(rc)) 104 { 105 RTPrintf("tstFileAio: FATAL ERROR - Failed to submit tasks. rc=%Rrc\n", rc); 106 cErrors++; 107 break; 108 } 109 110 /* Wait */ 111 RTFILEAIOREQ aReqsCompleted[TSTFILEAIO_MAX_REQS_IN_FLIGHT]; 112 uint32_t cCompleted = 0; 113 rc = RTFileAioCtxWait(hAioContext, cReqs, RT_INDEFINITE_WAIT, 114 aReqsCompleted, TSTFILEAIO_MAX_REQS_IN_FLIGHT, 115 &cCompleted); 116 if (RT_FAILURE(rc)) 117 { 118 RTPrintf("tstFileAio: FATAL ERROR - Waiting failed. rc=%Rrc\n", rc); 119 cErrors++; 120 break; 121 } 122 123 if (!fWrite) 124 { 125 for (uint32_t i = 0; i < cCompleted; i++) 126 { 127 /* Compare that we read the right stuff. */ 128 void *pvBuf = RTFileAioReqGetUser(aReqsCompleted[i]); 129 130 if (memcmp(pvBuf, pvTestBuf, cbTestBuf) != 0) 131 { 132 RTPrintf("tstFileAio: FATAL ERROR - Unexpected content in memory.\n"); 133 cErrors++; 134 break; 135 } 136 memset(pvBuf, 0, cbTestBuf); 137 } 138 } 185 RTPrintf("tstFileAio: FATAL ERROR - Failed to asssociate file with async I/O context. rc=%Rrc\n", rc); 186 cErrors++; 139 187 } 140 141 /* Free buffers. */142 for (unsigned i = 0; i < RT_ELEMENTS(apvBuf); i++)143 RTMemPageFree(apvBuf[i]);144 145 /* Free requests. */146 for (unsigned i = 0; i < RT_ELEMENTS(aReqs); i++)147 RTFileAioReqDestroy(aReqs[i]);148 149 NanoTS = RTTimeNanoTS() - NanoTS;150 unsigned SpeedKBs = cbTestFile / (NanoTS / 1000000000.0) / 1024;151 152 RTPrintf("tstFileAio: Completed simple %s test: %d.%03d MB/sec\n",153 fWrite ? "write" : "read",154 SpeedKBs / 1000,155 SpeedKBs % 1000);156 188 157 189 rc = RTFileAioCtxDestroy(hAioContext); … … 190 222 RTPrintf("tstFileAio: Preparing test file, this can take some time and needs quite a bit of harddisk\n"); 191 223 tstFileAioTestReadWriteBasic(File, true, pvTestBuf, 64*_1K, 100*_1M); 192 tstFileAioTestReadWriteBasic(File, false, pvTestBuf, 64*_1K, 100*_1M); 193 224 /* Reopen the file. */ 194 225 RTFileClose(File); 226 rc = RTFileOpen(&File, "tstFileAio#1.tst", RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_ASYNC_IO); 227 if (RT_SUCCESS(rc)) 228 { 229 tstFileAioTestReadWriteBasic(File, false, pvTestBuf, 64*_1K, 100*_1M); 230 RTFileClose(File); 231 } 232 else 233 { 234 RTPrintf("tstFileAio: FATAL ERROR - Failed to open file #1. rc=%Rrc\n", rc); 235 cErrors++; 236 } 237 238 /* Cleanup */ 195 239 RTMemFree(pvTestBuf); 196 240 RTFileDelete("tstFileAio#1.tst");
Note:
See TracChangeset
for help on using the changeset viewer.