Index: trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp	(revision 101644)
+++ trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp	(revision 101645)
@@ -480,4 +480,10 @@
 /** The test handle. */
 static RTTEST       g_hTest;
+/** The page size of the system. */
+static uint32_t     g_cbPage;
+/** Page offset mask. */
+static uintptr_t    g_fPageOffset;
+/** Page shift in bits. */
+static uint32_t     g_cPageShift;
 /** The number of nanoseconds a RTTimeNanoTS call takes.
  * This is used for adjusting loop count estimates.  */
@@ -3914,7 +3920,7 @@
     RTTestISub("sendfile");
 # ifdef RT_OS_LINUX
-    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - PAGE_OFFSET_MASK);
+    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - g_fPageOffset);
 # else
-    uint64_t const cbFileMax = RT_MIN(cbFile, SSIZE_MAX - PAGE_OFFSET_MASK);
+    uint64_t const cbFileMax = RT_MIN(cbFile, SSIZE_MAX - g_fPageOffset);
 # endif
     signal(SIGPIPE, SIG_IGN);
@@ -3959,5 +3965,5 @@
 
         cbToSend /= 2;
-    } while (cbToSend >= PAGE_SIZE && ((unsigned)bFiller - 0xf7U) < 64);
+    } while (cbToSend >= g_cbPage && ((unsigned)bFiller - 0xf7U) < 64);
 
     /*
@@ -4174,5 +4180,5 @@
     }
 
-    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - PAGE_OFFSET_MASK);
+    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - g_fPageOffset);
     signal(SIGPIPE, SIG_IGN);
 
@@ -4216,5 +4222,5 @@
 
         cbToSend /= 2;
-    } while (cbToSend >= PAGE_SIZE && ((unsigned)bFiller - 0xf7U) < 64);
+    } while (cbToSend >= g_cbPage && ((unsigned)bFiller - 0xf7U) < 64);
 
     /*
@@ -4398,5 +4404,5 @@
     }
 
-    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - PAGE_OFFSET_MASK);
+    uint64_t const cbFileMax = RT_MIN(cbFile, UINT32_MAX - g_fPageOffset);
     signal(SIGPIPE, SIG_IGN);
 
@@ -4782,5 +4788,4 @@
      * Do uncached access, must be page aligned.
      */
-    uint32_t cbPage = PAGE_SIZE;
     memset(pbBuf, 0x66, cbBuf);
     if (!g_fIgnoreNoCache || hFileNoCache != NIL_RTFILE)
@@ -4789,7 +4794,7 @@
         for (size_t offBuf = 0; offBuf < cbBuf; )
         {
-            uint32_t const cPagesLeft   = (uint32_t)((cbBuf - offBuf) / cbPage);
+            uint32_t const cPagesLeft   = (uint32_t)((cbBuf - offBuf) / g_cbPage);
             uint32_t const cPagesToRead = RTRandU32Ex(1, cPagesLeft);
-            size_t const   cbToRead     = cPagesToRead * (size_t)cbPage;
+            size_t const   cbToRead     = cPagesToRead * (size_t)g_cbPage;
             size_t cbActual = 0;
             RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, &pbBuf[offBuf], cbToRead, &cbActual), VINF_SUCCESS);
@@ -4803,6 +4808,6 @@
                 else
                 {
-                    memset(&pbBuf[offBuf], 0x11, cbPage);
-                    offBuf += cbPage;
+                    memset(&pbBuf[offBuf], 0x11, g_cbPage);
+                    offBuf += g_cbPage;
                 }
             }
@@ -4899,6 +4904,6 @@
             if (iAlign & 2) /* end is page aligned */
             {
-                cbLeft -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
-                pbCur  -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
+                cbLeft -= (uintptr_t)pbCur & g_fPageOffset;
+                pbCur  -= (uintptr_t)pbCur & g_fPageOffset;
             }
 
@@ -4909,5 +4914,5 @@
             size_t cbSeg       = cbLeft != 0 ? RTRandU32Ex(0, cbSegMax) : 0;
             if (iAlign & 1) /* start is page aligned */
-                cbSeg += ((uintptr_t)pbCur - cbSeg) & PAGE_OFFSET_MASK;
+                cbSeg += ((uintptr_t)pbCur - cbSeg) & g_fPageOffset;
 
             if (iSeg - iZeroSeg < cZeroSegs)
@@ -5161,10 +5166,9 @@
         RTTESTI_CHECK_RC(RTFileSeek(ahFiles[iFile], 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS);
 
-        uint32_t cbPage = PAGE_SIZE;
         for (size_t offBuf = 0; offBuf < cbBuf; )
         {
-            uint32_t const cPagesLeft    = (uint32_t)((cbBuf - offBuf) / cbPage);
+            uint32_t const cPagesLeft    = (uint32_t)((cbBuf - offBuf) / g_cbPage);
             uint32_t const cPagesToWrite = RTRandU32Ex(1, cPagesLeft);
-            size_t const   cbToWrite     = cPagesToWrite * (size_t)cbPage;
+            size_t const   cbToWrite     = cPagesToWrite * (size_t)g_cbPage;
             size_t cbActual = 0;
             RTTESTI_CHECK_RC(RTFileWrite(ahFiles[iFile], &pbBuf[offBuf], cbToWrite, &cbActual), VINF_SUCCESS);
@@ -5182,6 +5186,6 @@
                 else
                 {
-                    memset(&pbBuf[offBuf], 0x11, cbPage);
-                    offBuf += cbPage;
+                    memset(&pbBuf[offBuf], 0x11, g_cbPage);
+                    offBuf += g_cbPage;
                 }
             }
@@ -5272,6 +5276,6 @@
             if (iAlign & 2) /* end is page aligned */
             {
-                cbLeft -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
-                pbCur  -= (uintptr_t)pbCur & PAGE_OFFSET_MASK;
+                cbLeft -= (uintptr_t)pbCur & g_fPageOffset;
+                pbCur  -= (uintptr_t)pbCur & g_fPageOffset;
             }
 
@@ -5282,5 +5286,5 @@
             size_t cbSeg       = cbLeft != 0 ? RTRandU32Ex(0, cbSegMax) : 0;
             if (iAlign & 1) /* start is page aligned */
-                cbSeg += ((uintptr_t)pbCur - cbSeg) & PAGE_OFFSET_MASK;
+                cbSeg += ((uintptr_t)pbCur - cbSeg) & g_fPageOffset;
 
             if (iSeg - iZeroSeg < cZeroSegs)
@@ -5371,5 +5375,5 @@
     PROFILE_FN(RTFileFlush(hFile1), g_nsTestRun, "RTFileFlush");
 
-    size_t   cbBuf = PAGE_SIZE;
+    size_t   cbBuf = g_cbPage;
     uint8_t *pbBuf = (uint8_t *)RTMemPageAlloc(cbBuf);
     RTTESTI_CHECK_RETV(pbBuf != NULL);
@@ -5391,5 +5395,5 @@
 {
     uint8_t *pbCur = &pbMapping[offMapping];
-    for (size_t offFlush = 0; offFlush < cbFlush; offFlush += PAGE_SIZE)
+    for (size_t offFlush = 0; offFlush < cbFlush; offFlush += g_cbPage)
         *(size_t volatile *)&pbCur[offFlush + 8] = cbFlush;
 # ifdef RT_OS_WINDOWS
@@ -5473,9 +5477,9 @@
          * Time page-ins just for fun.
          */
-        size_t const cPages = cbMapping >> PAGE_SHIFT;
+        size_t const cPages = cbMapping >> g_cPageShift;
         size_t uDummy = 0;
         uint64_t ns = RTTimeNanoTS();
         for (size_t iPage = 0; iPage < cPages; iPage++)
-            uDummy += ASMAtomicReadU8(&pbMapping[iPage << PAGE_SHIFT]);
+            uDummy += ASMAtomicReadU8(&pbMapping[iPage << g_cPageShift]);
         ns = RTTimeNanoTS() - ns;
         RTTestIValueF(ns / cPages, RTTESTUNIT_NS_PER_OCCURRENCE,  "page-in %s", s_apszStates[enmState]);
@@ -5511,5 +5515,5 @@
             if (enmState == kMMap_ReadWrite)
             {
-                static size_t const s_acbFlush[] = { PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 3, PAGE_SIZE * 8, PAGE_SIZE * 16, _2M };
+                static size_t const s_acbFlush[] = { g_cbPage, g_cbPage * 2, g_cbPage * 3, g_cbPage * 8, g_cbPage * 16, _2M };
                 for (unsigned iFlushSize = 0 ; iFlushSize < RT_ELEMENTS(s_acbFlush); iFlushSize++)
                 {
@@ -5549,5 +5553,5 @@
                                 RTTESTI_CHECK_RC(RTFileRead(hFileNoCache, pbBuf, cbToRead, NULL), VINF_SUCCESS);
 
-                                for (size_t offFlush = 0; offFlush < cbToRead; offFlush += PAGE_SIZE)
+                                for (size_t offFlush = 0; offFlush < cbToRead; offFlush += g_cbPage)
                                     if (*(size_t volatile *)&pbBuf[offFlush + 8] != cbFlush)
                                     {
@@ -5642,107 +5646,110 @@
      * Memory mappings without open handles (pretty common).
      */
-    for (uint32_t i = 0; i < 32; i++)
-    {
-        /* Create a new file, 256 KB in size, and fill it with random bytes.
-           Try uncached access if we can to force the page-in to do actual reads. */
-        char szFile2[FSPERF_MAX_PATH + 32];
-        memcpy(szFile2, g_szDir, g_cchDir);
-        RTStrPrintf(&szFile2[g_cchDir], sizeof(szFile2) - g_cchDir, "mmap-%u.noh", i);
-        RTFILE hFile2 = NIL_RTFILE;
-        int rc = (i & 3) == 3 ? VERR_TRY_AGAIN
-               : RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_NO_CACHE);
-        if (RT_FAILURE(rc))
-        {
-            RTTESTI_CHECK_RC_BREAK(RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE),
-                                   VINF_SUCCESS);
-        }
-
-        static char  s_abContentUnaligned[256*1024 + PAGE_SIZE - 1];
-        char * const pbContent = &s_abContentUnaligned[PAGE_SIZE - ((uintptr_t)&s_abContentUnaligned[0] & PAGE_OFFSET_MASK)];
-        size_t const cbContent = 256*1024;
-        RTRandBytes(pbContent, cbContent);
-        RTTESTI_CHECK_RC(rc = RTFileWrite(hFile2, pbContent, cbContent, NULL), VINF_SUCCESS);
-        RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
-        if (RT_SUCCESS(rc))
-        {
-            /* Reopen the file with normal caching.  Every second time, we also
-               does a read-only open of it to confuse matters. */
-            RTFILE hFile3 = NIL_RTFILE;
-            if ((i & 3) == 3)
-                RTTESTI_CHECK_RC(RTFileOpen(&hFile3, szFile2, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE), VINF_SUCCESS);
-            hFile2 = NIL_RTFILE;
-            RTTESTI_CHECK_RC_BREAK(RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE),
-                                   VINF_SUCCESS);
-            if ((i & 3) == 1)
-                RTTESTI_CHECK_RC(RTFileOpen(&hFile3, szFile2, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE), VINF_SUCCESS);
-
-            /* Memory map it read-write (no COW). */
+    char *pbContentUnaligned = (char *)RTMemAlloc(256*1024 + g_cbPage - 1);
+    RTTESTI_CHECK(pbContentUnaligned != NULL);
+    if (pbContentUnaligned)
+    {
+        for (uint32_t i = 0; i < 32; i++)
+        {
+            /* Create a new file, 256 KB in size, and fill it with random bytes.
+               Try uncached access if we can to force the page-in to do actual reads. */
+            char szFile2[FSPERF_MAX_PATH + 32];
+            memcpy(szFile2, g_szDir, g_cchDir);
+            RTStrPrintf(&szFile2[g_cchDir], sizeof(szFile2) - g_cchDir, "mmap-%u.noh", i);
+            RTFILE hFile2 = NIL_RTFILE;
+            int rc = (i & 3) == 3 ? VERR_TRY_AGAIN
+                   : RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_NO_CACHE);
+            if (RT_FAILURE(rc))
+            {
+                RTTESTI_CHECK_RC_BREAK(RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE),
+                                       VINF_SUCCESS);
+            }
+
+            char * const pbContent = &pbContentUnaligned[g_cbPage - ((uintptr_t)&pbContentUnaligned[0] & g_fPageOffset)];
+            size_t const cbContent = 256*1024;
+            RTRandBytes(pbContent, cbContent);
+            RTTESTI_CHECK_RC(rc = RTFileWrite(hFile2, pbContent, cbContent, NULL), VINF_SUCCESS);
+            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
+            if (RT_SUCCESS(rc))
+            {
+                /* Reopen the file with normal caching.  Every second time, we also
+                   does a read-only open of it to confuse matters. */
+                RTFILE hFile3 = NIL_RTFILE;
+                if ((i & 3) == 3)
+                    RTTESTI_CHECK_RC(RTFileOpen(&hFile3, szFile2, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE), VINF_SUCCESS);
+                hFile2 = NIL_RTFILE;
+                RTTESTI_CHECK_RC_BREAK(RTFileOpen(&hFile2, szFile2, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE),
+                                       VINF_SUCCESS);
+                if ((i & 3) == 1)
+                    RTTESTI_CHECK_RC(RTFileOpen(&hFile3, szFile2, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE), VINF_SUCCESS);
+
+                /* Memory map it read-write (no COW). */
 #ifdef RT_OS_WINDOWS
-            HANDLE hSection = CreateFileMapping((HANDLE)RTFileToNative(hFile2), NULL, PAGE_READWRITE, 0, cbContent, NULL);
-            CHECK_WINAPI_CALL(hSection != NULL);
-            uint8_t *pbMapping = (uint8_t *)MapViewOfFile(hSection, FILE_MAP_WRITE, 0, 0, cbContent);
-            CHECK_WINAPI_CALL(pbMapping != NULL);
-            CHECK_WINAPI_CALL(CloseHandle(hSection) == TRUE);
+                HANDLE hSection = CreateFileMapping((HANDLE)RTFileToNative(hFile2), NULL, PAGE_READWRITE, 0, cbContent, NULL);
+                CHECK_WINAPI_CALL(hSection != NULL);
+                uint8_t *pbMapping = (uint8_t *)MapViewOfFile(hSection, FILE_MAP_WRITE, 0, 0, cbContent);
+                CHECK_WINAPI_CALL(pbMapping != NULL);
+                CHECK_WINAPI_CALL(CloseHandle(hSection) == TRUE);
 # else
-            uint8_t *pbMapping = (uint8_t *)mmap(NULL, cbContent, PROT_READ | PROT_WRITE, MAP_SHARED,
-                                                 (int)RTFileToNative(hFile2), 0);
-            if ((void *)pbMapping == MAP_FAILED)
-                pbMapping = NULL;
-            RTTESTI_CHECK_MSG(pbMapping != NULL, ("errno=%s (%d)\n", strerror(errno), errno));
+                uint8_t *pbMapping = (uint8_t *)mmap(NULL, cbContent, PROT_READ | PROT_WRITE, MAP_SHARED,
+                                                     (int)RTFileToNative(hFile2), 0);
+                if ((void *)pbMapping == MAP_FAILED)
+                    pbMapping = NULL;
+                RTTESTI_CHECK_MSG(pbMapping != NULL, ("errno=%s (%d)\n", strerror(errno), errno));
 # endif
 
-            /* Close the file handles. */
-            if ((i & 7) == 7)
-            {
-                RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
-                hFile3 = NIL_RTFILE;
+                /* Close the file handles. */
+                if ((i & 7) == 7)
+                {
+                    RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
+                    hFile3 = NIL_RTFILE;
+                }
+                RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
+                if ((i & 7) == 5)
+                {
+                    RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
+                    hFile3 = NIL_RTFILE;
+                }
+                if (pbMapping)
+                {
+                    RTThreadSleep(2); /* fudge for cleanup/whatever */
+
+                    /* Page in the mapping by comparing with the content we wrote above. */
+                    RTTESTI_CHECK(memcmp(pbMapping, pbContent, cbContent) == 0);
+
+                    /* Now dirty everything by inverting everything. */
+                    size_t *puCur = (size_t *)pbMapping;
+                    size_t  cLeft = cbContent / sizeof(*puCur);
+                    while (cLeft-- > 0)
+                    {
+                        *puCur = ~*puCur;
+                        puCur++;
+                    }
+
+                    /* Sync it all. */
+#  ifdef RT_OS_WINDOWS
+                    //CHECK_WINAPI_CALL(FlushViewOfFile(pbMapping, cbContent) == TRUE);
+                    SetLastError(0);
+                    if (FlushViewOfFile(pbMapping, cbContent) != TRUE)
+                        RTTestIFailed("line %u, i=%u: FlushViewOfFile(%p, %#zx) failed: %u / %#x", __LINE__, i,
+                                      pbMapping, cbContent, GetLastError(), RTNtLastStatusValue());
+#  else
+                    RTTESTI_CHECK(msync(pbMapping, cbContent, MS_SYNC) == 0);
+#  endif
+
+                    /* Unmap it. */
+# ifdef RT_OS_WINDOWS
+                    CHECK_WINAPI_CALL(UnmapViewOfFile(pbMapping) == TRUE);
+# else
+                    RTTESTI_CHECK(munmap(pbMapping, cbContent) == 0);
+# endif
+                }
+
+                if (hFile3 != NIL_RTFILE)
+                    RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
             }
-            RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS);
-            if ((i & 7) == 5)
-            {
-                RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
-                hFile3 = NIL_RTFILE;
-            }
-            if (pbMapping)
-            {
-                RTThreadSleep(2); /* fudge for cleanup/whatever */
-
-                /* Page in the mapping by comparing with the content we wrote above. */
-                RTTESTI_CHECK(memcmp(pbMapping, pbContent, cbContent) == 0);
-
-                /* Now dirty everything by inverting everything. */
-                size_t *puCur = (size_t *)pbMapping;
-                size_t  cLeft = cbContent / sizeof(*puCur);
-                while (cLeft-- > 0)
-                {
-                    *puCur = ~*puCur;
-                    puCur++;
-                }
-
-                /* Sync it all. */
-#  ifdef RT_OS_WINDOWS
-                //CHECK_WINAPI_CALL(FlushViewOfFile(pbMapping, cbContent) == TRUE);
-                SetLastError(0);
-                if (FlushViewOfFile(pbMapping, cbContent) != TRUE)
-                    RTTestIFailed("line %u, i=%u: FlushViewOfFile(%p, %#zx) failed: %u / %#x", __LINE__, i,
-                                  pbMapping, cbContent, GetLastError(), RTNtLastStatusValue());
-#  else
-                RTTESTI_CHECK(msync(pbMapping, cbContent, MS_SYNC) == 0);
-#  endif
-
-                /* Unmap it. */
-# ifdef RT_OS_WINDOWS
-                CHECK_WINAPI_CALL(UnmapViewOfFile(pbMapping) == TRUE);
-# else
-                RTTESTI_CHECK(munmap(pbMapping, cbContent) == 0);
-# endif
-            }
-
-            if (hFile3 != NIL_RTFILE)
-                RTTESTI_CHECK_RC(RTFileClose(hFile3), VINF_SUCCESS);
-        }
-        RTTESTI_CHECK_RC(RTFileDelete(szFile2), VINF_SUCCESS);
-    }
-
+            RTTESTI_CHECK_RC(RTFileDelete(szFile2), VINF_SUCCESS);
+        }
+    }
 
 #else
@@ -6387,4 +6394,9 @@
     RTListInit(&g_ManyTreeHead);
 
+    /* Query page size, offset mask and page shift of the system. */
+    g_cbPage      = RTSystemGetPageSize();
+    g_fPageOffset = RTSystemGetPageOffsetMask();
+    g_cPageShift  = RTSystemGetPageShift();
+
     /*
      * Default values.
