- Timestamp:
- Mar 27, 2019 2:14:16 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/fs/FsPerf.cpp
r77894 r77895 51 51 #include <iprt/string.h> 52 52 #include <iprt/stream.h> 53 #include <iprt/system.h> 53 54 #include <iprt/test.h> 54 55 #include <iprt/time.h> … … 67 68 # include <sys/uio.h> 68 69 # endif 70 # include <sys/sendfile.h> 69 71 #endif 70 72 … … 3242 3244 3243 3245 3246 #ifdef RT_OS_LINUX 3247 DECL_FORCE_INLINE(int) fsPerfCopyWorkerSendFile(RTFILE hFile1, RTFILE hFile2, size_t cbFile) 3248 { 3249 RTTESTI_CHECK_RC_RET(RTFileSeek(hFile2, 0, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS, rcCheck); 3250 3251 loff_t off = 0; 3252 ssize_t cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), &off, cbFile); 3253 if (cbSent > 0 && (size_t)cbSent == cbFile) 3254 return 0; 3255 3256 int rc = VERR_GENERAL_FAILURE; 3257 if (cbSent < 0) 3258 { 3259 rc = RTErrConvertFromErrno(errno); 3260 RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)", cbFile, cbSent, errno, rc); 3261 } 3262 else 3263 RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)", 3264 cbFile, cbSent, cbFile, cbSent - cbFile); 3265 return rc; 3266 } 3267 #endif /* RT_OS_LINUX */ 3268 3269 3244 3270 static void fsPerfCopy(void) 3245 3271 { … … 3330 3356 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 3331 3357 RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS); 3358 3359 #ifdef RT_OS_LINUX 3360 /* 3361 * On linux we can also use sendfile between two files, except for 2.5.x to 2.6.33. 3362 */ 3363 char szRelease[64]; 3364 RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szRelease, sizeof(szRelease)); 3365 bool const fSendFileBetweenFiles = RTStrVersionCompare(szRelease, "2.5.0") < 0 3366 || RTStrVersionCompare(szRelease, "2.6.33") >= 0; 3367 if (fSendFileBetweenFiles) 3368 { 3369 /* Copy the whole file: */ 3370 hFile1 = NIL_RTFILE; 3371 RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS); 3372 RTFileDelete(g_szDir2); 3373 hFile2 = NIL_RTFILE; 3374 RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS); 3375 ssize_t cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), NULL, cbFile); 3376 if (cbSent < 0) 3377 RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)", 3378 cbFile, cbSent, errno, RTErrConvertFromErrno(errno)); 3379 else if ((size_t)cbSent != cbFile) 3380 RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)", 3381 cbFile, cbSent, cbFile, cbSent - cbFile); 3382 RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS); 3383 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 3384 RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS); 3385 3386 /* Try copy a little bit too much: */ 3387 hFile1 = NIL_RTFILE; 3388 RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS); 3389 RTFileDelete(g_szDir2); 3390 hFile2 = NIL_RTFILE; 3391 RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS); 3392 size_t cbToCopy = cbFile + RTRandU32Ex(1, _64M); 3393 cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), NULL, cbToCopy); 3394 if (cbSent < 0) 3395 RTTestIFailed("sendfile(file,file,NULL,%#zx) failed (%zd): %d (%Rrc)", 3396 cbToCopy, cbSent, errno, RTErrConvertFromErrno(errno)); 3397 else if ((size_t)cbSent != cbFile) 3398 RTTestIFailed("sendfile(file,file,NULL,%#zx) returned %#zx, expected %#zx (diff %zd)", 3399 cbToCopy, cbSent, cbFile, cbSent - cbFile); 3400 RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS); 3401 RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS); 3402 3403 /* Do partial copy: */ 3404 hFile2 = NIL_RTFILE; 3405 RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS); 3406 for (uint32_t i = 0; i < 64; i++) 3407 { 3408 cbToCopy = RTRandU32Ex(0, cbFile - 1); 3409 uint32_t const offFile = RTRandU32Ex(1, (uint64_t)RT_MIN(cbFile - cbToCopy, UINT32_MAX)); 3410 RTTESTI_CHECK_RC_BREAK(RTFileSeek(hFile2, offFile, RTFILE_SEEK_BEGIN, NULL), VINF_SUCCESS); 3411 loff_t offFile2 = offFile; 3412 cbSent = sendfile((int)RTFileToNative(hFile2), (int)RTFileToNative(hFile1), &offFile2, cbToCopy); 3413 if (cbSent < 0) 3414 RTTestIFailed("sendfile(file,file,%#x,%#zx) failed (%zd): %d (%Rrc)", 3415 offFile, cbToCopy, cbSent, errno, RTErrConvertFromErrno(errno)); 3416 else if ((size_t)cbSent != cbToCopy) 3417 RTTestIFailed("sendfile(file,file,%#x,%#zx) returned %#zx, expected %#zx (diff %zd)", 3418 offFile, cbToCopy, cbSent, cbToCopy, cbSent - cbToCopy); 3419 else if (offFile2 != (loff_t)(offFile + cbToCopy)) 3420 RTTestIFailed("sendfile(file,file,%#x,%#zx) returned %#zx + off=%#RX64, expected off %#x", 3421 offFile, cbToCopy, cbSent, offFile2, offFile + cbToCopy); 3422 } 3423 RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS); 3424 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 3425 RTTESTI_CHECK_RC(RTFileCompare(g_szDir, g_szDir2), VINF_SUCCESS); 3426 } 3427 #endif 3332 3428 3333 3429 /* … … 3403 3499 /* We could benchmark RTFileCopyPart with various block sizes and whatnot... 3404 3500 But it's currently well covered by the two previous operations. */ 3501 3502 #ifdef RT_OS_LINUX 3503 if (fSendFileBetweenFiles) 3504 { 3505 hFile1 = NIL_RTFILE; 3506 RTTESTI_CHECK_RC(RTFileOpen(&hFile1, g_szDir, RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READ), VINF_SUCCESS); 3507 RTFileDelete(g_szDir2); 3508 hFile2 = NIL_RTFILE; 3509 RTTESTI_CHECK_RC(RTFileOpen(&hFile2, g_szDir2, RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_WRITE), VINF_SUCCESS); 3510 PROFILE_COPY_FN("sendfile/overwrite", fsPerfCopyWorkerSendFile(hFile1, hFile2, cbFile)); 3511 RTTESTI_CHECK_RC(RTFileClose(hFile2), VINF_SUCCESS); 3512 RTTESTI_CHECK_RC(RTFileClose(hFile1), VINF_SUCCESS); 3513 } 3514 #endif 3515 3405 3516 } 3406 3517
Note:
See TracChangeset
for help on using the changeset viewer.