diff --git a/changelog.md b/changelog.md index 1fb6377a28..5656a86c30 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ [//]: # "Changes:" - Changed `std/osfiles.copyFile` to allow to specify `bufferSize` instead of a hardcoded one. +- Changed `std/osfiles.copyFile` to use `POSIX_FADV_SEQUENTIAL` hints for kernel-level aggressive sequential read-aheads. [//]: # "Additions:" diff --git a/lib/std/private/osfiles.nim b/lib/std/private/osfiles.nim index b7957fa4f1..948df4211f 100644 --- a/lib/std/private/osfiles.nim +++ b/lib/std/private/osfiles.nim @@ -203,6 +203,7 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}; bufferSize = 1 ## `-d:nimLegacyCopyFile` is used. ## ## `copyFile` allows to specify `bufferSize` to improve I/O performance. + ## ## See also: ## * `CopyFlag enum`_ ## * `copyDir proc`_ @@ -243,6 +244,13 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}; bufferSize = 1 if not open(d, dest, fmWrite): close(s) raiseOSError(osLastError(), dest) + + # Hints for kernel-level aggressive sequential low-fragmentation read-aheads: + # https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fadvise.html + when defined(linux) or defined(osx): + discard posix_fadvise(getFileHandle(d), 0.cint, 0.cint, POSIX_FADV_SEQUENTIAL) + discard posix_fadvise(getFileHandle(s), 0.cint, 0.cint, POSIX_FADV_SEQUENTIAL) + var buf = alloc(bufferSize) while true: var bytesread = readBuffer(s, buf, bufferSize)