VirtualBox

Ignore:
Timestamp:
Mar 10, 2019 3:10:26 AM (6 years ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

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

    r77566 r77630  
    6060# ifndef RT_OS_OS2
    6161#  include <sys/mman.h>
     62#  include <sys/uio.h>
    6263# endif
    6364#endif
     
    18311832
    18321833
     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.   */
     1836static int myFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead)
     1837{
     1838    int rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, NULL);
     1839    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    }
     1861    return rc;
     1862}
     1863#endif
     1864
     1865
    18331866void fsPerfRead(RTFILE hFile1, RTFILE hFileNoCache, uint64_t cbFile)
    18341867{
     
    18871920        fsPerfCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf);
    18881921    }
    1889 #endif
    18901922
    18911923    /*
     
    19772009     */
    19782010    RTTESTI_CHECK_RC(RTFileSeek(hFile1, 0, RTFILE_SEEK_END, NULL), VINF_SUCCESS);
    1979 #ifdef RT_OS_WINDOWS
     2011# ifdef RT_OS_WINDOWS
    19802012    IO_STATUS_BLOCK Ios       = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    19812013    NTSTATUS rcNt = NtReadFile((HANDLE)RTFileToNative(hFile1), NULL, NULL, NULL, &Ios, pbBuf, 0, NULL, NULL);
     
    19892021    RTTESTI_CHECK(Ios.Status == STATUS_END_OF_FILE);
    19902022    RTTESTI_CHECK(Ios.Information == 0);
    1991 #else
     2023# else
    19922024    ssize_t cbRead = read((int)RTFileToNative(hFile1), pbBuf, 0);
    19932025    RTTESTI_CHECK(cbRead == 0);
     2026# endif
     2027
     2028#else
     2029    RT_NOREF(hFileNoCache);
     2030#endif
     2031
     2032    /*
     2033     * Scatter read function operation.  While we have RTFileSgReadAt, it is
     2034     * generally not available, so we have to call readv directly.
     2035     */
     2036#ifdef RT_OS_WINDOWS
     2037    /** @todo RTFileSgReadAt is just a RTFileReadAt loop for windows NT.  Need
     2038     *        to use ReadFileScatter (nocache + page aligned). */
     2039#elif !defined(RT_OS_OS2)
     2040
     2041# ifdef UIO_MAXIOV
     2042    RTSGSEG aSegs[UIO_MAXIOV];
     2043# else
     2044    RTSGSEG aSegs[512];
     2045# endif
     2046    RTSGBUF SgBuf;
     2047    uint32_t cIncr = 1;
     2048    for (uint32_t cSegs = 1; cSegs <= RT_ELEMENTS(aSegs); cSegs += cIncr)
     2049    {
     2050        size_t const cbSeg    = cbBuf / cSegs;
     2051        size_t const cbToRead = cbSeg * cSegs;
     2052        for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     2053        {
     2054            aSegs[iSeg].cbSeg = cbSeg;
     2055            aSegs[iSeg].pvSeg = &pbBuf[cbToRead - (iSeg + 1) * cbSeg];
     2056        }
     2057        RTSgBufInit(&SgBuf, &aSegs[0], cSegs);
     2058        int rc = myFileSgReadAt(hFile1, 0, &SgBuf, cbToRead, NULL);
     2059        if (RT_SUCCESS(rc))
     2060            for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     2061            {
     2062                if (!fsPerfCheckReadBuf(__LINE__, iSeg * cbSeg, &pbBuf[cbToRead - (iSeg + 1) * cbSeg], cbSeg))
     2063                {
     2064                    cSegs = RT_ELEMENTS(aSegs);
     2065                    break;
     2066                }
     2067            }
     2068        else
     2069        {
     2070            RTTestIFailed("RTFileSgReadAt failed: %Rrc - cSegs=%u cbSegs=%#zx cbToRead=%#zx", rc, cSegs, cbSeg, cbToRead);
     2071            break;
     2072        }
     2073        if (cSegs == 16)
     2074            cIncr = 7;
     2075        else if (cSegs == 16 * 7 + 16 /*= 128*/)
     2076            cIncr = 64;
     2077    }
     2078
     2079    for (uint32_t iTest = 0; iTest < 128; iTest++)
     2080    {
     2081        uint32_t cSegs     = RTRandU32Ex(1, RT_ELEMENTS(aSegs));
     2082        uint32_t iZeroSeg  = cSegs > 10 ? RTRandU32Ex(0, cSegs - 1)                    : UINT32_MAX / 2;
     2083        uint32_t cZeroSegs = cSegs > 10 ? RTRandU32Ex(1, RT_MIN(cSegs - iZeroSeg, 25)) : 0;
     2084        size_t   cbToRead  = 0;
     2085        size_t   cbLeft    = cbBuf;
     2086        uint8_t *pbCur     = &pbBuf[cbBuf];
     2087        for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     2088        {
     2089            uint32_t iAlign = RTRandU32Ex(0, 3);
     2090            if (iAlign & 2) /* end is page aligned */
     2091            {
     2092                cbLeft -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
     2093                pbCur  -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
     2094            }
     2095
     2096            size_t cbSegOthers = (cSegs - iSeg) * _8K;
     2097            size_t cbSegMax    = cbLeft > cbSegOthers ? cbLeft - cbSegOthers
     2098                               : cbLeft > cSegs       ? cbLeft - cSegs
     2099                               : cbLeft;
     2100            size_t cbSeg       = cbLeft != 0 ? RTRandU32Ex(0, cbSegMax) : 0;
     2101            if (iAlign & 1) /* start is page aligned */
     2102                cbSeg += ((uintptr_t)pbCur - cbSeg) & PAGE_OFFSET_MASK;
     2103
     2104            if (iSeg - iZeroSeg < cZeroSegs)
     2105                cbSeg = 0;
     2106
     2107            cbToRead += cbSeg;
     2108            cbLeft   -= cbSeg;
     2109            pbCur    -= cbSeg;
     2110            aSegs[iSeg].cbSeg = cbSeg;
     2111            aSegs[iSeg].pvSeg = pbCur;
     2112        }
     2113
     2114        uint64_t offFile = cbToRead < cbFile ? RTRandU64Ex(0, cbFile - cbToRead) : 0;
     2115        RTSgBufInit(&SgBuf, &aSegs[0], cSegs);
     2116        int rc = myFileSgReadAt(hFile1, offFile, &SgBuf, cbToRead, NULL);
     2117        if (RT_SUCCESS(rc))
     2118            for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     2119            {
     2120                if (!fsPerfCheckReadBuf(__LINE__, offFile, (uint8_t *)aSegs[iSeg].pvSeg, aSegs[iSeg].cbSeg))
     2121                {
     2122                    RTTestIFailureDetails("iSeg=%#x cSegs=%#x cbSeg=%#zx cbToRead=%#zx\n", iSeg, cSegs, aSegs[iSeg].cbSeg, cbToRead);
     2123                    iTest = _16K;
     2124                    break;
     2125                }
     2126                offFile += aSegs[iSeg].cbSeg;
     2127            }
     2128        else
     2129        {
     2130            RTTestIFailed("RTFileSgReadAt failed: %Rrc - cSegs=%#x cbToRead=%#zx", rc, cSegs, cbToRead);
     2131            break;
     2132        }
     2133    }
     2134
    19942135#endif
    19952136
     
    20122153    fsPerfCheckReadBuf(__LINE__, cbFile / 2, pbBuf, _4K);
    20132154#endif
     2155
    20142156
    20152157    RTMemPageFree(pbBuf, cbBuf);
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