Changeset 76914 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jan 21, 2019 12:19:00 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 128285
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r76903 r76914 251 251 kCmdOpt_Seek, 252 252 kCmdOpt_NoSeek, 253 kCmdOpt_FSync, 254 kCmdOpt_NoFSync, 255 kCmdOpt_MMap, 256 kCmdOpt_NoMMap, 253 257 254 258 kCmdOpt_End … … 259 263 * Global Variables * 260 264 *********************************************************************************************************************************/ 261 262 265 /** Command line parameters */ 263 266 static const RTGETOPTDEF g_aCmdOptions[] = … … 305 308 { "--seek", kCmdOpt_Seek, RTGETOPT_REQ_NOTHING }, 306 309 { "--no-seek", kCmdOpt_NoSeek, RTGETOPT_REQ_NOTHING }, 310 { "--fsync", kCmdOpt_FSync, RTGETOPT_REQ_NOTHING }, 311 { "--no-fsync", kCmdOpt_NoFSync, RTGETOPT_REQ_NOTHING }, 312 { "--mmap", kCmdOpt_MMap, RTGETOPT_REQ_NOTHING }, 313 { "--no-mmap", kCmdOpt_NoMMap, RTGETOPT_REQ_NOTHING }, 307 314 308 315 { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, … … 339 346 static bool g_fRm = true; 340 347 static bool g_fChSize = true; 341 static bool g_fSeek = true;342 348 static bool g_fRead = true; 343 349 static bool g_fWrite = true; 350 static bool g_fSeek = true; 351 static bool g_fFSync = true; 352 static bool g_fMMap = true; 344 353 /** @} */ 345 354 … … 1392 1401 * Checks the content read from the file fsPerfIoPrepFile() prepared. 1393 1402 */ 1394 bool fsP refCheckReadBuf(unsigned uLineNo, uint64_t off, uint8_t const *pbBuf, size_t cbBuf, uint8_t bFiller = 0xf6)1403 bool fsPerfCheckReadBuf(unsigned uLineNo, uint64_t off, uint8_t const *pbBuf, size_t cbBuf, uint8_t bFiller = 0xf6) 1395 1404 { 1396 1405 uint32_t cMismatches = 0; … … 1454 1463 * Sets up write buffer with offset markers and fillers. 1455 1464 */ 1456 void fsP refFillWriteBuf(uint64_t off, uint8_t *pbBuf, size_t cbBuf, uint8_t bFiller = 0xf6)1465 void fsPerfFillWriteBuf(uint64_t off, uint8_t *pbBuf, size_t cbBuf, uint8_t bFiller = 0xf6) 1457 1466 { 1458 1467 uint32_t offBlock = (uint32_t)(off & (_1K - 1)); … … 1753 1762 } 1754 1763 } 1755 fsP refCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf);1764 fsPerfCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf); 1756 1765 } 1757 1766 #endif … … 1835 1844 } 1836 1845 } 1837 fsP refCheckReadBuf(__LINE__, 0, pbBuf, cbBuf);1846 fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf); 1838 1847 1839 1848 /* … … 1872 1881 RTTESTI_CHECK(Ios.Information == _4K); 1873 1882 RTTESTI_CHECK(RTFileTell(hFile1) == cbFile / 2 + _4K); 1874 fsP refCheckReadBuf(__LINE__, cbFile / 2, pbBuf, _4K);1883 fsPerfCheckReadBuf(__LINE__, cbFile / 2, pbBuf, _4K); 1875 1884 #endif 1876 1885 … … 1952 1961 for (uint32_t i = 0; i < RT_ELEMENTS(aRuns); i++, bFiller) 1953 1962 { 1954 fsP refFillWriteBuf(aRuns[i].offFile, pbBuf, cbBuf, bFiller);1955 fsP refCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf, bFiller);1963 fsPerfFillWriteBuf(aRuns[i].offFile, pbBuf, cbBuf, bFiller); 1964 fsPerfCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf, bFiller); 1956 1965 1957 1966 RTTESTI_CHECK_RC(RTFileSeek(hFile1, aRuns[i].offFile, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); … … 1977 1986 1978 1987 RTTESTI_CHECK_RC(RTFileReadAt(hFile1, aRuns[i].offFile, pbBuf, cbBuf, NULL), VINF_SUCCESS); 1979 fsP refCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf, bFiller);1988 fsPerfCheckReadBuf(__LINE__, aRuns[i].offFile, pbBuf, cbBuf, bFiller); 1980 1989 } 1981 1990 … … 1987 1996 for (unsigned iFile = 0; iFile < RT_ELEMENTS(ahFiles); iFile++, bFiller++) 1988 1997 { 1989 fsP refFillWriteBuf(0, pbBuf, cbBuf, bFiller);1990 fsP refCheckReadBuf(__LINE__, 0, pbBuf, cbBuf, bFiller);1998 fsPerfFillWriteBuf(0, pbBuf, cbBuf, bFiller); 1999 fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf, bFiller); 1991 2000 RTTESTI_CHECK_RC(RTFileSeek(ahFiles[iFile], 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); 1992 2001 … … 2002 2011 { 2003 2012 RTTESTI_CHECK_RC(RTFileReadAt(hFile1, offBuf, pbBuf, cbToWrite, NULL), VINF_SUCCESS); 2004 fsP refCheckReadBuf(__LINE__, offBuf, pbBuf, cbToWrite, bFiller);2013 fsPerfCheckReadBuf(__LINE__, offBuf, pbBuf, cbToWrite, bFiller); 2005 2014 offBuf += cbActual; 2006 2015 } … … 2019 2028 2020 2029 RTTESTI_CHECK_RC(RTFileReadAt(ahFiles[iFile], 0, pbBuf, cbBuf, NULL), VINF_SUCCESS); 2021 fsP refCheckReadBuf(__LINE__, 0, pbBuf, cbBuf, bFiller);2030 fsPerfCheckReadBuf(__LINE__, 0, pbBuf, cbBuf, bFiller); 2022 2031 } 2023 2032 … … 2036 2045 2037 2046 RTTESTI_CHECK_RC(RTFileRead(hFile1, pbBuf, _4K, NULL), VINF_SUCCESS); 2038 fsP refCheckReadBuf(__LINE__, cbFile - _4K, pbBuf, _4K, pbBuf[0x8]);2047 fsPerfCheckReadBuf(__LINE__, cbFile - _4K, pbBuf, _4K, pbBuf[0x8]); 2039 2048 #endif 2040 2049 … … 2060 2069 RT_NOREF(hFileNoCache, hFileWriteThru); 2061 2070 RTMemPageFree(pbBuf, cbBuf); 2071 } 2072 2073 2074 /** 2075 * Worker for testing RTFileFlush. 2076 */ 2077 DECL_FORCE_INLINE(int) fsPerfFSyncWorker(RTFILE hFile1, uint64_t cbFile, uint8_t *pbBuf, size_t cbBuf, uint64_t *poffFile) 2078 { 2079 if (*poffFile + cbBuf <= cbFile) 2080 { /* likely */ } 2081 else 2082 { 2083 RTTESTI_CHECK_RC(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); 2084 *poffFile = 0; 2085 } 2086 2087 RTTESTI_CHECK_RC_RET(RTFileWrite(hFile1, pbBuf, cbBuf, NULL), VINF_SUCCESS, rcCheck); 2088 RTTESTI_CHECK_RC_RET(RTFileFlush(hFile1), VINF_SUCCESS, rcCheck); 2089 2090 *poffFile += cbBuf; 2091 return VINF_SUCCESS; 2092 } 2093 2094 2095 void fsPerfFSync(RTFILE hFile1, uint64_t cbFile) 2096 { 2097 RTTestISub("fsync"); 2098 2099 RTTESTI_CHECK_RC(RTFileFlush(hFile1), VINF_SUCCESS); 2100 2101 PROFILE_FN(RTFileFlush(hFile1), g_nsTestRun, "RTFileFlush"); 2102 2103 size_t cbBuf = PAGE_SIZE; 2104 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf); 2105 RTTESTI_CHECK_RETV(pbBuf != NULL); 2106 memset(pbBuf, 0xf4, cbBuf); 2107 2108 RTTESTI_CHECK_RC(RTFileSeek(hFile1, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); 2109 uint64_t offFile = 0; 2110 PROFILE_FN(fsPerfFSyncWorker(hFile1, cbFile, pbBuf, cbBuf, &offFile), g_nsTestRun, "RTFileWrite[Page]/RTFileFlush"); 2111 2112 RTMemPageFree(pbBuf, cbBuf); 2113 } 2114 2115 2116 void fsPerfMMap(RTFILE hFile1, RTFILE hFileNoCache, uint64_t cbFile) 2117 { 2118 RTTestISub("mmap"); 2119 #if defined(RT_OS_WINDOWS) 2120 static const char * const s_apszStates[] = { "readonly", "writecopy", "readwrite" }; 2121 enum { kMMap_ReadOnly = 0, kMMap_WriteCopy, kMMap_ReadWrite, kMMap_End }; 2122 for (int enmState = kMMap_ReadOnly; enmState < kMMap_End; enmState++) 2123 { 2124 /* 2125 * Do the mapping. 2126 */ 2127 size_t cbMapping = (size_t)cbFile; 2128 if (cbMapping != cbFile) 2129 cbMapping = _256M; 2130 uint8_t *pbMapping; 2131 2132 # ifdef RT_OS_WINDOWS 2133 HANDLE hSection; 2134 for (;; cbMapping /= 2) 2135 { 2136 hSection = CreateFileMapping((HANDLE)RTFileToNative(hFile1), NULL, 2137 enmState == kMMap_ReadOnly ? PAGE_READONLY 2138 : enmState == kMMap_WriteCopy ? PAGE_WRITECOPY : PAGE_READWRITE, 2139 (uint32_t)(cbMapping >> 32), (uint32_t)cbMapping, NULL); 2140 DWORD dwErr1 = GetLastError(); 2141 DWORD dwErr2 = 0; 2142 if (hSection != NULL) 2143 { 2144 pbMapping = (uint8_t *)MapViewOfFile(hSection, 2145 enmState == kMMap_ReadOnly ? FILE_MAP_READ 2146 : enmState == kMMap_WriteCopy ? FILE_MAP_COPY 2147 : FILE_MAP_WRITE, 2148 0, 0, cbMapping); 2149 if (pbMapping) 2150 break; 2151 dwErr2 = GetLastError(); 2152 CloseHandle(hSection); 2153 } 2154 if (cbMapping <= _2M) 2155 { 2156 RTTestIFailed("%u: CreateFileMapping or MapViewOfFile failed: %u, %u", enmState, dwErr1, dwErr2); 2157 return; 2158 } 2159 } 2160 # else 2161 for (;; cbMapping /= 2) 2162 { 2163 pbMapping = (uint8_t *)mmap(NULL, cbMapping, 2164 enmState == kMMap_ReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, 2165 enmState == kMMap_WriteCopy ? MAP_PRIVATE : MAP_SHARED, 2166 (int)RTFileToNative(hFile1), cbMapping); 2167 if ((void *)pbMapping != MAP_FAILED) 2168 break; 2169 RTTESTI_CHECK_MSG_RETV(cbMapping > _2M, ("errno=%d", errno)); 2170 } 2171 # endif 2172 2173 /* 2174 * Time page-ins just for fun. 2175 */ 2176 size_t const cPages = cbMapping >> PAGE_SHIFT; 2177 size_t uDummy = 0; 2178 uint64_t ns = RTTimeNanoTS(); 2179 for (size_t iPage = 0; iPage < cPages; iPage++) 2180 uDummy += ASMAtomicReadU8(&pbMapping[iPage << PAGE_SHIFT]); 2181 ns = RTTimeNanoTS() - ns; 2182 RTTestIValueF(ns / cPages, RTTESTUNIT_NS_PER_OCCURRENCE, "page-in %s", s_apszStates[enmState]); 2183 2184 /* Check the content. */ 2185 fsPerfCheckReadBuf(__LINE__, 0, pbMapping, cbMapping); 2186 2187 if (enmState != kMMap_ReadOnly) 2188 { 2189 /* Write stuff to the first two megabytes. In the COW case, we'll detect 2190 corruption of shared data during content checking of the RW iterations. */ 2191 fsPerfFillWriteBuf(0, pbMapping, _2M, 0xf7); 2192 if (enmState == kMMap_ReadWrite) 2193 { 2194 /* For RW we can try read back from the file handle and check if we get 2195 a match there first. */ 2196 uint8_t abBuf[_4K]; 2197 for (uint32_t off = 0; off < _2M; off += sizeof(abBuf)) 2198 { 2199 RTTESTI_CHECK_RC(RTFileReadAt(hFile1, off, abBuf, sizeof(abBuf), NULL), VINF_SUCCESS); 2200 fsPerfCheckReadBuf(__LINE__, off, abBuf, sizeof(abBuf), 0xf7); 2201 } 2202 # ifdef RT_OS_WINDOWS 2203 RTTESTI_CHECK(FlushViewOfFile(pbMapping, _2M)); 2204 # else 2205 RTTESTI_CHECK(msync(pbMapping, _2M, MS_SYNC) == 0); 2206 # endif 2207 2208 /* 2209 * Time modifying and flushing a few different number of pages. 2210 */ 2211 static size_t const s_acbFlush[] = { PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 3, PAGE_SIZE * 8, PAGE_SIZE * 16, _2M }; 2212 for (unsigned iFlushSize = 0 ; iFlushSize < RT_ELEMENTS(s_acbFlush); iFlushSize++) 2213 { 2214 size_t const cbFlush = s_acbFlush[iFlushSize]; 2215 if (cbFlush > cbMapping) 2216 continue; 2217 2218 size_t const cFlushes = cbMapping / cbFlush; 2219 uint8_t *pbCur = pbMapping; 2220 ns = RTTimeNanoTS(); 2221 for (size_t iFlush = 0; iFlush < cFlushes; iFlush++, pbCur += cbFlush) 2222 { 2223 for (size_t offFlush = 0; offFlush < cbFlush; offFlush += PAGE_SIZE) 2224 *(size_t volatile *)&pbCur[offFlush + 8] = cbFlush; 2225 # ifdef RT_OS_WINDOWS 2226 RTTESTI_CHECK(FlushViewOfFile(pbCur, cbFlush)); 2227 # else 2228 RTTESTI_CHECK(msync(pbCur, cbFlush, MS_SYNC) == 0); 2229 # endif 2230 } 2231 ns = RTTimeNanoTS() - ns; 2232 RTTestIValueF(ns / cPages, RTTESTUNIT_NS_PER_OCCURRENCE, "touch/flush/%zu", cbFlush); 2233 2234 /* 2235 * Check that all the changes made it thru to the file: 2236 */ 2237 size_t cbBuf = _2M; 2238 uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(_2M); 2239 if (!pbBuf) 2240 { 2241 cbBuf = _4K; 2242 pbBuf = (uint8_t *)RTMemPageAlloc(_2M); 2243 } 2244 if (pbBuf) 2245 { 2246 RTTESTI_CHECK_RC(RTFileSeek(hFileNoCache, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); 2247 size_t const cbToCheck = cFlushes * cbFlush; 2248 unsigned cErrors = 0; 2249 for (size_t offBuf = 0; cErrors < 32 && offBuf < cbToCheck; offBuf += cbBuf) 2250 { 2251 size_t cbToRead = RT_MIN(cbBuf, cbToCheck - offBuf); 2252 RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, pbBuf, cbToRead, NULL), VINF_SUCCESS); 2253 2254 for (size_t offFlush = 0; offFlush < cbToRead; offFlush += PAGE_SIZE) 2255 if (*(size_t volatile *)&pbBuf[offFlush + 8] != cbFlush) 2256 { 2257 RTTestIFailed("Flush issue at offset #%zx: %#zx, expected %#zx (cbFlush=%#zx)", 2258 offBuf, *(size_t volatile *)&pbBuf[offFlush + 8], cbFlush, cbFlush); 2259 if (++cErrors > 32) 2260 break; 2261 } 2262 } 2263 RTMemPageFree(pbBuf, cbBuf); 2264 } 2265 } 2266 } 2267 } 2268 2269 /* 2270 * Unmap it. 2271 */ 2272 # ifdef RT_OS_WINDOWS 2273 RTTESTI_CHECK(UnmapViewOfFile(pbMapping)); 2274 RTTESTI_CHECK(CloseHandle(hSection)); 2275 # else 2276 RTTESTI_CHECK(munmap(pbMapping, cbMapping) == 0); 2277 # endif 2278 } 2279 2280 RT_NOREF(hFileNoCache); 2281 #else 2282 RTTestSkipped(g_hTest, "not supported/implemented"); 2283 RT_NOREF(hFile1, hFileNoCache, cbFile); 2284 #endif 2062 2285 } 2063 2286 … … 2127 2350 fsPerfIoReadBlockSize(hFile1, cbFile, g_acbIoBlocks[i]); 2128 2351 } 2129 /** @todo mmap */2130 2352 if (g_fMMap) 2353 fsPerfMMap(hFile1, hFileNoCache, cbFile); 2131 2354 if (g_fWrite) 2132 2355 { … … 2136 2359 fsPerfIoWriteBlockSize(hFile1, cbFile, g_acbIoBlocks[i]); 2137 2360 } 2138 2361 if (g_fFSync) 2362 fsPerfFSync(hFile1, cbFile); 2139 2363 } 2140 2364 … … 2268 2492 g_fWrite = true; 2269 2493 g_fSeek = true; 2494 g_fFSync = true; 2495 g_fMMap = true; 2270 2496 break; 2271 2497 … … 2288 2514 g_fWrite = false; 2289 2515 g_fSeek = false; 2516 g_fFSync = false; 2517 g_fMMap = false; 2290 2518 break; 2291 2519 … … 2307 2535 CASE_OPT(Rm); 2308 2536 CASE_OPT(ChSize); 2309 CASE_OPT(Seek);2310 2537 CASE_OPT(Read); 2311 2538 CASE_OPT(Write); 2539 CASE_OPT(Seek); 2540 CASE_OPT(FSync); 2541 CASE_OPT(MMap); 2312 2542 #undef CASE_OPT 2313 2543 … … 2385 2615 if (g_fChSize) 2386 2616 fsPerfChSize(); 2387 if (g_fRead || g_fWrite || g_fSeek )2617 if (g_fRead || g_fWrite || g_fSeek || g_fFSync || g_fMMap) 2388 2618 fsPerfIo(); 2389 2619 }
Note:
See TracChangeset
for help on using the changeset viewer.