VirtualBox

Changeset 77634 in vbox


Ignore:
Timestamp:
Mar 10, 2019 2:49:03 PM (6 years ago)
Author:
vboxsync
Message:

FsPerf: Added writev testcase. bugref:9172 ticketref:17360

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp

    r77630 r77634  
    18321832
    18331833
    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. */
     1835DECLINLINE(int) myFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead)
    18371836{
    18381837    int rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, NULL);
    18391838    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);
    18611840    return rc;
    18621841}
    1863 #endif
    18641842
    18651843
     
    20312009
    20322010    /*
    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.
    20352012     */
    20362013#ifdef RT_OS_WINDOWS
    20372014    /** @todo RTFileSgReadAt is just a RTFileReadAt loop for windows NT.  Need
    20382015     *        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 */
    20402017
    20412018# ifdef UIO_MAXIOV
     
    20682045        else
    20692046        {
    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);
    20712048            break;
    20722049        }
     
    21282105        else
    21292106        {
    2130             RTTestIFailed("RTFileSgReadAt failed: %Rrc - cSegs=%#x cbToRead=%#zx", rc, cSegs, cbToRead);
     2107            RTTestIFailed("myFileSgReadAt failed: %Rrc - cSegs=%#x cbToRead=%#zx", rc, cSegs, cbToRead);
    21312108            break;
    21322109        }
     
    22042181
    22052182
     2183/** pwritev is too new to be useful, so we use the writev api via this wrapper. */
     2184DECLINLINE(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
    22062193void fsPerfWrite(RTFILE hFile1, RTFILE hFileNoCache, RTFILE hFileWriteThru, uint64_t cbFile)
    22072194{
     
    22202207    }
    22212208
     2209    uint8_t bFiller = 0x88;
     2210
     2211#if 1
    22222212    /*
    22232213     * Start at the beginning and write out the full buffer in random small chunks, thereby
     
    22292219        uint32_t cbMax;
    22302220    } aRuns[] = { { 0, 127 }, { cbFile - cbBuf, UINT32_MAX }, { 0, UINT32_MAX -1 }};
    2231     uint8_t bFiller = 0x88;
    22322221    for (uint32_t i = 0; i < RT_ELEMENTS(aRuns); i++, bFiller)
    22332222    {
     
    23162305     */
    23172306    RTTESTI_CHECK_RC(RTFileSeek(hFile1, -_4K, RTFILE_SEEK_END, NULL), VINF_SUCCESS);
    2318 #ifdef RT_OS_WINDOWS
     2307# ifdef RT_OS_WINDOWS
    23192308    IO_STATUS_BLOCK Ios        = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    23202309    NTSTATUS rcNt = NtWriteFile((HANDLE)RTFileToNative(hFile1), NULL, NULL, NULL, &Ios, pbBuf, 0, NULL, NULL);
     
    23222311    RTTESTI_CHECK(Ios.Status == STATUS_SUCCESS);
    23232312    RTTESTI_CHECK(Ios.Information == 0);
    2324 #else
     2313# else
    23252314    ssize_t cbWritten = write((int)RTFileToNative(hFile1), pbBuf, 0);
    23262315    RTTESTI_CHECK(cbWritten == 0);
    2327 #endif
     2316# endif
    23282317    RTTESTI_CHECK_RC(RTFileRead(hFile1, pbBuf, _4K, NULL), VINF_SUCCESS);
    23292318    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
    23302427
    23312428    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette