Changeset 77634 in vbox
- Timestamp:
- Mar 10, 2019 2:49:03 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r77630 r77634 1832 1832 1833 1833 1834 #if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) /** @todo use list-io on OS/2 (readv uses heap+read). */ 1835 /** Our version of RTFileSgReadAt for hosts where preadv is too new. */ 1836 static int myFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead) 1834 /** preadv is too new to be useful, so we use the readv api via this wrapper. */ 1835 DECLINLINE(int) myFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead) 1837 1836 { 1838 1837 int rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, NULL); 1839 1838 if (RT_SUCCESS(rc)) 1840 { 1841 ssize_t cbRead = readv(RTFileToNative(hFile), (const struct iovec *)pSgBuf->paSegs, pSgBuf->cSegs); 1842 if (cbRead < 0) 1843 { 1844 rc = RTErrConvertFromErrno(errno); 1845 if (pcbRead) 1846 *pcbRead = 0; 1847 } 1848 else 1849 { 1850 if (pcbRead) 1851 *pcbRead = cbRead; 1852 if ((size_t)cbRead == cbToRead || pcbRead) 1853 rc = VINF_SUCCESS; 1854 else 1855 { 1856 rc = VERR_READ_ERROR; 1857 RTTestIFailed("readv: off=%#llx cbToRead=%#zx returned %#zx", off, cbToRead, cbRead); 1858 } 1859 } 1860 } 1839 rc = RTFileSgRead(hFile, pSgBuf, cbToRead, pcbRead); 1861 1840 return rc; 1862 1841 } 1863 #endif1864 1842 1865 1843 … … 2031 2009 2032 2010 /* 2033 * Scatter read function operation. While we have RTFileSgReadAt, it is 2034 * generally not available, so we have to call readv directly. 2011 * Scatter read function operation. 2035 2012 */ 2036 2013 #ifdef RT_OS_WINDOWS 2037 2014 /** @todo RTFileSgReadAt is just a RTFileReadAt loop for windows NT. Need 2038 2015 * to use ReadFileScatter (nocache + page aligned). */ 2039 #elif !defined(RT_OS_OS2) 2016 #elif !defined(RT_OS_OS2) /** @todo implement RTFileSg using list i/o */ 2040 2017 2041 2018 # ifdef UIO_MAXIOV … … 2068 2045 else 2069 2046 { 2070 RTTestIFailed(" RTFileSgReadAt failed: %Rrc - cSegs=%u cbSegs=%#zx cbToRead=%#zx", rc, cSegs, cbSeg, cbToRead);2047 RTTestIFailed("myFileSgReadAt failed: %Rrc - cSegs=%u cbSegs=%#zx cbToRead=%#zx", rc, cSegs, cbSeg, cbToRead); 2071 2048 break; 2072 2049 } … … 2128 2105 else 2129 2106 { 2130 RTTestIFailed(" RTFileSgReadAt failed: %Rrc - cSegs=%#x cbToRead=%#zx", rc, cSegs, cbToRead);2107 RTTestIFailed("myFileSgReadAt failed: %Rrc - cSegs=%#x cbToRead=%#zx", rc, cSegs, cbToRead); 2131 2108 break; 2132 2109 } … … 2204 2181 2205 2182 2183 /** pwritev is too new to be useful, so we use the writev api via this wrapper. */ 2184 DECLINLINE(int) myFileSgWriteAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToWrite, size_t *pcbWritten) 2185 { 2186 int rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, NULL); 2187 if (RT_SUCCESS(rc)) 2188 rc = RTFileSgWrite(hFile, pSgBuf, cbToWrite, pcbWritten); 2189 return rc; 2190 } 2191 2192 2206 2193 void fsPerfWrite(RTFILE hFile1, RTFILE hFileNoCache, RTFILE hFileWriteThru, uint64_t cbFile) 2207 2194 { … … 2220 2207 } 2221 2208 2209 uint8_t bFiller = 0x88; 2210 2211 #if 1 2222 2212 /* 2223 2213 * Start at the beginning and write out the full buffer in random small chunks, thereby … … 2229 2219 uint32_t cbMax; 2230 2220 } aRuns[] = { { 0, 127 }, { cbFile - cbBuf, UINT32_MAX }, { 0, UINT32_MAX -1 }}; 2231 uint8_t bFiller = 0x88;2232 2221 for (uint32_t i = 0; i < RT_ELEMENTS(aRuns); i++, bFiller) 2233 2222 { … … 2316 2305 */ 2317 2306 RTTESTI_CHECK_RC(RTFileSeek(hFile1, -_4K, RTFILE_SEEK_END, NULL), VINF_SUCCESS); 2318 # ifdef RT_OS_WINDOWS2307 # ifdef RT_OS_WINDOWS 2319 2308 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 2320 2309 NTSTATUS rcNt = NtWriteFile((HANDLE)RTFileToNative(hFile1), NULL, NULL, NULL, &Ios, pbBuf, 0, NULL, NULL); … … 2322 2311 RTTESTI_CHECK(Ios.Status == STATUS_SUCCESS); 2323 2312 RTTESTI_CHECK(Ios.Information == 0); 2324 # else2313 # else 2325 2314 ssize_t cbWritten = write((int)RTFileToNative(hFile1), pbBuf, 0); 2326 2315 RTTESTI_CHECK(cbWritten == 0); 2327 # endif2316 # endif 2328 2317 RTTESTI_CHECK_RC(RTFileRead(hFile1, pbBuf, _4K, NULL), VINF_SUCCESS); 2329 2318 fsPerfCheckReadBuf(__LINE__, cbFile - _4K, pbBuf, _4K, pbBuf[0x8]); 2319 2320 #else 2321 RT_NOREF(hFileNoCache, hFileWriteThru); 2322 #endif 2323 2324 /* 2325 * Gather write function operation. 2326 */ 2327 #ifdef RT_OS_WINDOWS 2328 /** @todo RTFileSgWriteAt is just a RTFileWriteAt loop for windows NT. Need 2329 * to use WriteFileGather (nocache + page aligned). */ 2330 #elif !defined(RT_OS_OS2) /** @todo implement RTFileSg using list i/o */ 2331 2332 # ifdef UIO_MAXIOV 2333 RTSGSEG aSegs[UIO_MAXIOV]; 2334 # else 2335 RTSGSEG aSegs[512]; 2336 # endif 2337 RTSGBUF SgBuf; 2338 uint32_t cIncr = 1; 2339 for (uint32_t cSegs = 1; cSegs <= RT_ELEMENTS(aSegs); cSegs += cIncr, bFiller++) 2340 { 2341 size_t const cbSeg = cbBuf / cSegs; 2342 size_t const cbToWrite = cbSeg * cSegs; 2343 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) 2344 { 2345 aSegs[iSeg].cbSeg = cbSeg; 2346 aSegs[iSeg].pvSeg = &pbBuf[cbToWrite - (iSeg + 1) * cbSeg]; 2347 fsPerfFillWriteBuf(iSeg * cbSeg, (uint8_t *)aSegs[iSeg].pvSeg, cbSeg, bFiller); 2348 } 2349 RTSgBufInit(&SgBuf, &aSegs[0], cSegs); 2350 int rc = myFileSgWriteAt(hFile1, 0, &SgBuf, cbToWrite, NULL); 2351 if (RT_SUCCESS(rc)) 2352 { 2353 RTTESTI_CHECK_RC(RTFileReadAt(hFile1, 0, pbBuf, cbToWrite, NULL), VINF_SUCCESS); 2354 fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbToWrite, bFiller); 2355 } 2356 else 2357 { 2358 RTTestIFailed("myFileSgWriteAt failed: %Rrc - cSegs=%u cbSegs=%#zx cbToWrite=%#zx", rc, cSegs, cbSeg, cbToWrite); 2359 break; 2360 } 2361 if (cSegs == 16) 2362 cIncr = 7; 2363 else if (cSegs == 16 * 7 + 16 /*= 128*/) 2364 cIncr = 64; 2365 } 2366 2367 /* random stuff, including zero segments. */ 2368 for (uint32_t iTest = 0; iTest < 128; iTest++, bFiller++) 2369 { 2370 uint32_t cSegs = RTRandU32Ex(1, RT_ELEMENTS(aSegs)); 2371 uint32_t iZeroSeg = cSegs > 10 ? RTRandU32Ex(0, cSegs - 1) : UINT32_MAX / 2; 2372 uint32_t cZeroSegs = cSegs > 10 ? RTRandU32Ex(1, RT_MIN(cSegs - iZeroSeg, 25)) : 0; 2373 size_t cbToWrite = 0; 2374 size_t cbLeft = cbBuf; 2375 uint8_t *pbCur = &pbBuf[cbBuf]; 2376 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) 2377 { 2378 uint32_t iAlign = RTRandU32Ex(0, 3); 2379 if (iAlign & 2) /* end is page aligned */ 2380 { 2381 cbLeft -= (uintptr_t)pbCur & PAGE_OFFSET_MASK; 2382 pbCur -= (uintptr_t)pbCur & PAGE_OFFSET_MASK; 2383 } 2384 2385 size_t cbSegOthers = (cSegs - iSeg) * _8K; 2386 size_t cbSegMax = cbLeft > cbSegOthers ? cbLeft - cbSegOthers 2387 : cbLeft > cSegs ? cbLeft - cSegs 2388 : cbLeft; 2389 size_t cbSeg = cbLeft != 0 ? RTRandU32Ex(0, cbSegMax) : 0; 2390 if (iAlign & 1) /* start is page aligned */ 2391 cbSeg += ((uintptr_t)pbCur - cbSeg) & PAGE_OFFSET_MASK; 2392 2393 if (iSeg - iZeroSeg < cZeroSegs) 2394 cbSeg = 0; 2395 2396 cbToWrite += cbSeg; 2397 cbLeft -= cbSeg; 2398 pbCur -= cbSeg; 2399 aSegs[iSeg].cbSeg = cbSeg; 2400 aSegs[iSeg].pvSeg = pbCur; 2401 } 2402 2403 uint64_t const offFile = cbToWrite < cbFile ? RTRandU64Ex(0, cbFile - cbToWrite) : 0; 2404 uint64_t offFill = offFile; 2405 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++) 2406 if (aSegs[iSeg].cbSeg) 2407 { 2408 fsPerfFillWriteBuf(offFill, (uint8_t *)aSegs[iSeg].pvSeg, aSegs[iSeg].cbSeg, bFiller); 2409 offFill += aSegs[iSeg].cbSeg; 2410 } 2411 2412 RTSgBufInit(&SgBuf, &aSegs[0], cSegs); 2413 int rc = myFileSgWriteAt(hFile1, offFile, &SgBuf, cbToWrite, NULL); 2414 if (RT_SUCCESS(rc)) 2415 { 2416 RTTESTI_CHECK_RC(RTFileReadAt(hFile1, offFile, pbBuf, cbToWrite, NULL), VINF_SUCCESS); 2417 fsPerfCheckReadBuf(__LINE__, offFile, pbBuf, cbToWrite, bFiller); 2418 } 2419 else 2420 { 2421 RTTestIFailed("myFileSgWriteAt failed: %Rrc - cSegs=%#x cbToWrite=%#zx", rc, cSegs, cbToWrite); 2422 break; 2423 } 2424 } 2425 2426 #endif 2330 2427 2331 2428 /*
Note:
See TracChangeset
for help on using the changeset viewer.