Skip to content

Commit

Permalink
Rollup merge of #79600 - nicokoch:kernel_copy_unixstream, r=m-ou-se
Browse files Browse the repository at this point in the history
std::io: Use sendfile for UnixStream

`UnixStream` was forgotten in #75272 .

Benchmark yields the following results.
Before:
`running 1 test
test sys::unix::kernel_copy::tests::bench_file_to_uds_copy        ... bench:      54,399 ns/iter (+/- 6,817) = 2409 MB/s`

After:
`running 1 test
test sys::unix::kernel_copy::tests::bench_file_to_uds_copy        ... bench:      18,627 ns/iter (+/- 6,007) = 7036 MB/s`
  • Loading branch information
GuillaumeGomez authored Dec 1, 2020
2 parents 3d631b0 + 5987451 commit 9e26fc6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
29 changes: 29 additions & 0 deletions library/std/src/sys/unix/kernel_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use crate::mem::ManuallyDrop;
use crate::net::TcpStream;
use crate::os::unix::fs::FileTypeExt;
use crate::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use crate::os::unix::net::UnixStream;
use crate::process::{ChildStderr, ChildStdin, ChildStdout};
use crate::ptr;
use crate::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -320,6 +321,34 @@ impl CopyWrite for &TcpStream {
}
}

impl CopyRead for UnixStream {
fn properties(&self) -> CopyParams {
// avoid the stat syscall since we can be fairly sure it's a socket
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
}
}

impl CopyRead for &UnixStream {
fn properties(&self) -> CopyParams {
// avoid the stat syscall since we can be fairly sure it's a socket
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
}
}

impl CopyWrite for UnixStream {
fn properties(&self) -> CopyParams {
// avoid the stat syscall since we can be fairly sure it's a socket
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
}
}

impl CopyWrite for &UnixStream {
fn properties(&self) -> CopyParams {
// avoid the stat syscall since we can be fairly sure it's a socket
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
}
}

impl CopyWrite for ChildStdin {
fn properties(&self) -> CopyParams {
CopyParams(FdMeta::Pipe, Some(self.as_raw_fd()))
Expand Down
29 changes: 29 additions & 0 deletions library/std/src/sys/unix/kernel_copy/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,35 @@ fn bench_file_to_socket_copy(b: &mut test::Bencher) {
});
}

#[bench]
fn bench_file_to_uds_copy(b: &mut test::Bencher) {
const BYTES: usize = 128 * 1024;
let src_path = temp_dir().join("uds-copy-bench-src");
let mut src = OpenOptions::new()
.create(true)
.truncate(true)
.read(true)
.write(true)
.open(src_path)
.unwrap();
src.write(&vec![0u8; BYTES]).unwrap();

let (mut sink, mut sink_drainer) = crate::os::unix::net::UnixStream::pair().unwrap();

crate::thread::spawn(move || {
let mut sink_buf = vec![0u8; 1024 * 1024];
loop {
sink_drainer.read(&mut sink_buf[..]).unwrap();
}
});

b.bytes = BYTES as u64;
b.iter(|| {
src.seek(SeekFrom::Start(0)).unwrap();
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
});
}

#[cfg(any(target_os = "linux", target_os = "android"))]
#[bench]
fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) {
Expand Down

0 comments on commit 9e26fc6

Please sign in to comment.