Repository navigation
Conversation
|
|
||
| [target.'cfg(unix)'.dependencies] | ||
| rustix = { workspace = true, features = ["fs"] } | ||
| rustix = { workspace = true, features = ["fs", "pipe"] } |
This comment was marked as low quality.
This comment was marked as low quality.
Sorry, something went wrong.
This comment was marked as low quality.
This comment was marked as low quality.
Sorry, something went wrong.
| // Increasing the output pipe capacity is optional and may be done once by | ||
| // callers that copy several inputs into the same output. | ||
| let _ = fcntl_setpipe_size(&mut *dest, MAX_ROOTLESS_PIPE_SIZE); | ||
| splice_unbounded_broker(source, dest) | ||
| } | ||
|
|
||
| /// Copy through a cached broker pipe without changing the output pipe capacity. | ||
| /// | ||
| /// Callers copying multiple sources may prepare their output once and reuse | ||
| /// this operation for each source. A failure to resize never prevents copying. | ||
| #[inline] | ||
| pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> SpliceRes { |
This comment was marked as low quality.
This comment was marked as low quality.
Sorry, something went wrong.
This comment was marked as low quality.
This comment was marked as low quality.
| // fcntl for input would not improve throughput since | ||
| // - sender with splice probably increased size already | ||
| // - sender without splice is bottleneck |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
c4d75cf to
34525a4
Compare
| // All operands share stdout. Resize its pipe once, even if the kernel | ||
| // refuses the optional increase, rather than retrying for every file. |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
34525a4 to
c7f35d0
Compare
| I: IntoIterator<Item = &'a OsString>, | ||
| { | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| if options.can_print_fast() { |
There was a problem hiding this comment.
the description mentions a regression test for mixed file/stdin order but i don't see it in the commit, please add it in tests/by-util/test_cat.rs
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
If we test something, it should count pipe2 call by strace.
a regression checks mixed file/stdin output order is unrelated with this PR.
| /// Copy through a cached broker pipe without changing the output pipe capacity. | ||
| /// | ||
| /// Callers copying multiple sources may prepare their output once and reuse | ||
| /// this operation for each source. A failure to resize never prevents copying. |
There was a problem hiding this comment.
this function never resizes, so "a failure to resize never prevents copying" is confusing here. could you please make this doc one line?
There was a problem hiding this comment.
I think we don't need this comment.
c7f35d0 to
736f4f1
Compare
Merging this PR will not alter performance1 warning, 1 note
Comparing Footnotes
|
736f4f1 to
adfcce3
Compare
|
Added the requested strace regression |
| } | ||
|
|
||
| #[test] | ||
| fn test_fast_copy_mixed_file_and_stdin_order() { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| let scene = TestScenario::new(util_name!()); | ||
| let probe = Command::new("strace") | ||
| .args(["-qq", "-o", "/dev/null", "-e", "trace=none"]) |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| let probe = Command::new("strace") | ||
| .args(["-qq", "-o", "/dev/null", "-e", "trace=none"]) | ||
| .arg(&scene.bin_path) | ||
| .args(["cat", "--help"]) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
adfcce3 to
74bd78d
Compare
| { | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| if options.can_print_fast() { | ||
| // All operands share stdout. Try to resize it once. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| /// Copy through a cached broker pipe without resizing the output pipe. | ||
| #[inline] | ||
| pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> SpliceRes { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
74bd78d to
e0daa92
Compare
| static PIPE_CACHE: Cell<Option<(PipeReader, PipeWriter)>> = const { Cell::new(None) }; | ||
| /// Cache the last destination's resize attempt, including failures. | ||
| /// Reused descriptor numbers may skip resizing, which is only an optimization. | ||
| static LAST_RESIZE_FD: Cell<Option<RawFd>> = const { Cell::new(None) }; |
There was a problem hiding this comment.
Yes. This looks very reasonable and helpful also for other utils.
| eprintln!("TEST SKIPPED: strace is unavailable"); | ||
| return; | ||
| }; | ||
| let trace = read_to_string(scene.fixtures.plus("trace")).unwrap_or_default(); |
There was a problem hiding this comment.
| let trace = read_to_string(scene.fixtures.plus("trace")).unwrap_or_default(); | |
| let trace = read_to_string(scene.fixtures.plus("trace")).unwrap(); |
I think this should panic if it is missing.
| use std::process::Command; | ||
|
|
||
| let scene = TestScenario::new(util_name!()); | ||
| let Ok(output) = Command::new("strace") |
There was a problem hiding this comment.
| let Ok(output) = Command::new("strace") | |
| let Ok(output) = std::process::Command::new("strace") |
Command is used just once.
|
Binary size comparison: |
Prepare stdout's pipe capacity once and reuse the broker copy for every input. On 30 files, resize attempts fall from 31 to 2. A strace regression checks one broker pipe and two resize attempts with cat /dev/null /dev/ null.
Closes #11700.