Skip to content

Commit ce98ec5

Browse files
committed
tee: improve throughput by raw syscall
1 parent 055a66b commit ce98ec5

2 files changed

Lines changed: 19 additions & 19 deletions

File tree

src/uu/tee/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ doctest = false
2121

2222
[dependencies]
2323
clap = { workspace = true }
24-
uucore = { workspace = true, features = ["libc", "parser", "signals"] }
24+
rustix = { workspace = true, features = ["stdio", "fs"] }
25+
uucore = { workspace = true, features = ["fs", "libc", "parser", "signals"] }
2526
fluent = { workspace = true }
2627

2728
[dev-dependencies]
2829
divan = { workspace = true }
29-
rustix = { workspace = true, features = ["stdio", "fs"] }
3030
tempfile = { workspace = true }
3131
uucore = { workspace = true, features = ["benchmark"] }
3232

src/uu/tee/src/tee.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,16 @@ impl MultiWriter {
197197

198198
fn write_flush(&mut self, buf: &[u8]) -> Result<()> {
199199
let mode = self.output_error_mode;
200-
self.writers.retain_mut(|writer| {
201-
let res = (|| {
202-
writer.inner.write_all(buf)?;
203-
writer.inner.flush()
204-
})();
205-
match res {
200+
self.writers
201+
.retain_mut(|writer| match writer.inner.write_all(buf) {
206202
Ok(()) => true,
207203
Err(e) => {
208204
if let Err(e) = process_error(mode, e, writer, &mut self.ignored_errors) {
209205
self.aborted.get_or_insert(e);
210206
}
211207
false
212208
}
213-
}
214-
});
209+
});
215210
self.aborted.take().map_or(
216211
if self.writers.is_empty() {
217212
// This error kind will never be raised by the standard
@@ -254,18 +249,23 @@ enum Writer {
254249
Stdout(std::io::Stdout),
255250
}
256251

257-
impl Write for Writer {
258-
fn write(&mut self, buf: &[u8]) -> Result<usize> {
252+
impl Writer {
253+
pub fn write_all(&mut self, buf: &[u8]) -> Result<()> {
254+
// raw syscall avoids buffering which is POSIX requirement
255+
// throughput is better than flush after write_all by unknown reason
256+
#[cfg(any(unix, target_os = "wasi"))]
259257
match self {
260-
Self::File(f) => f.write(buf),
261-
Self::Stdout(s) => s.write(buf),
258+
Self::File(f) => uucore::io::write_all_raw(f, buf),
259+
Self::Stdout(s) => uucore::io::write_all_raw(s, buf),
262260
}
263-
}
264-
265-
fn flush(&mut self) -> Result<()> {
261+
#[cfg(not(any(unix, target_os = "wasi")))]
266262
match self {
267-
Self::File(f) => f.flush(),
268-
Self::Stdout(s) => s.flush(),
263+
// File does not have line buffering
264+
Self::File(f) => f.write_all(buf),
265+
Self::Stdout(s) => {
266+
s.write_all(buf)?;
267+
s.flush() // todo: investigate how to remove flush overhead
268+
}
269269
}
270270
}
271271
}

0 commit comments

Comments
 (0)