diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index 16769ece5..2cdd3033a 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -362,6 +362,7 @@ uutils # * function names execfn +fadvise fstatfs getcwd mkfifoat diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index 89f8540f8..4f975000d 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore fname, ftype, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat oconv canonicalized fadvise Fadvise FADV DONTNEED ESPIPE bufferedoutput, SETFL +// spell-checker:ignore fname, ftype, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat oconv canonicalized Fadvise FADV DONTNEED ESPIPE bufferedoutput, SETFL mod blocks; mod bufferedoutput; diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index 320112c47..001ab16eb 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -//spell-checker:ignore TAOCP indegree fadvise FADV +//spell-checker:ignore TAOCP indegree FADV //spell-checker:ignore (libs) interner uclibc use clap::{Arg, ArgAction, Command}; use rustc_hash::FxHashMap; diff --git a/src/uucore/src/lib/features/pipes.rs b/src/uucore/src/lib/features/pipes.rs index b86283a21..f86988617 100644 --- a/src/uucore/src/lib/features/pipes.rs +++ b/src/uucore/src/lib/features/pipes.rs @@ -85,17 +85,7 @@ pub fn might_fuse(source: &impl AsFd) -> bool { /// splice all of source to dest /// returns Ok(()) at end of file #[inline] -pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io::Result<()> { - // avoid fcntl overhead for small input. splice twice to catch end of file. - if splice(&source, &dest, MAX_ROOTLESS_PIPE_SIZE)? == 0 - || splice(&source, &dest, MAX_ROOTLESS_PIPE_SIZE)? == 0 - { - return Ok(()); - } - // fcntl for input would not improve throughput since - // - sender with splice probably increased size already - // - sender without splice is bottleneck - let _ = fcntl_setpipe_size(&mut *dest, MAX_ROOTLESS_PIPE_SIZE); +fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io::Result<()> { while splice(&source, &dest, MAX_ROOTLESS_PIPE_SIZE)? > 0 {} Ok(()) } @@ -104,16 +94,11 @@ pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io: /// /// This should not be used if one of them are pipe to save resources #[inline] -pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> PipeRes { +fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> PipeRes { static PIPE_CACHE: OnceLock> = OnceLock::new(); let Some((pipe_rd, pipe_wr)) = PIPE_CACHE.get_or_init(|| pipe::().ok()) else { return Ok(Err(())); }; - // improve throughput - // no need to increase pipe size of input fd since - // - sender with splice probably increased size already - // - sender without splice is bottleneck - let _ = fcntl_setpipe_size(&mut *dest, MAX_ROOTLESS_PIPE_SIZE); loop { match splice(&source, &pipe_wr, MAX_ROOTLESS_PIPE_SIZE) { @@ -129,9 +114,16 @@ pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> Pipe } /// try splice_unbounded 1st and splice_unbounded_broker if both of in/output are not pipe +/// This includes read ahead and optimization for stdout's pipe size #[inline] pub fn splice_unbounded_auto(source: &impl AsFd, dest: &mut impl AsFd) -> PipeRes { - if splice_unbounded(source, dest).is_err() { + // fcntl for input would not improve throughput since + // - sender with splice probably increased size already + // - sender without splice is bottleneck + let is_pipe_out = fcntl_setpipe_size(&mut *dest, MAX_ROOTLESS_PIPE_SIZE).is_ok(); + // pre-generate page caches for splice + let is_file_in = rustix::fs::fadvise(source, 0, None, rustix::fs::Advice::Sequential).is_ok(); + if (is_file_in && !is_pipe_out) || splice_unbounded(source, dest).is_err() { // input or output is not pipe return splice_unbounded_broker(source, dest); } diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 2500bfb1e..309a93ac0 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname fadvise FADV DONTNEED +// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat abcdefghijklm abcdefghi nabcde nabcdefg abcdefg fifoname FADV DONTNEED use uutests::at_and_ucmd; use uutests::new_ucmd;