Skip to content

Commit 9e26fc6

Browse files
Rollup merge of #79600 - nicokoch:kernel_copy_unixstream, r=m-ou-se
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`
2 parents 3d631b0 + 5987451 commit 9e26fc6

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

library/std/src/sys/unix/kernel_copy.rs

+29
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use crate::mem::ManuallyDrop;
5656
use crate::net::TcpStream;
5757
use crate::os::unix::fs::FileTypeExt;
5858
use crate::os::unix::io::{AsRawFd, FromRawFd, RawFd};
59+
use crate::os::unix::net::UnixStream;
5960
use crate::process::{ChildStderr, ChildStdin, ChildStdout};
6061
use crate::ptr;
6162
use crate::sync::atomic::{AtomicBool, Ordering};
@@ -320,6 +321,34 @@ impl CopyWrite for &TcpStream {
320321
}
321322
}
322323

324+
impl CopyRead for UnixStream {
325+
fn properties(&self) -> CopyParams {
326+
// avoid the stat syscall since we can be fairly sure it's a socket
327+
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
328+
}
329+
}
330+
331+
impl CopyRead for &UnixStream {
332+
fn properties(&self) -> CopyParams {
333+
// avoid the stat syscall since we can be fairly sure it's a socket
334+
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
335+
}
336+
}
337+
338+
impl CopyWrite for UnixStream {
339+
fn properties(&self) -> CopyParams {
340+
// avoid the stat syscall since we can be fairly sure it's a socket
341+
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
342+
}
343+
}
344+
345+
impl CopyWrite for &UnixStream {
346+
fn properties(&self) -> CopyParams {
347+
// avoid the stat syscall since we can be fairly sure it's a socket
348+
CopyParams(FdMeta::Socket, Some(self.as_raw_fd()))
349+
}
350+
}
351+
323352
impl CopyWrite for ChildStdin {
324353
fn properties(&self) -> CopyParams {
325354
CopyParams(FdMeta::Pipe, Some(self.as_raw_fd()))

library/std/src/sys/unix/kernel_copy/tests.rs

+29
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,35 @@ fn bench_file_to_socket_copy(b: &mut test::Bencher) {
118118
});
119119
}
120120

121+
#[bench]
122+
fn bench_file_to_uds_copy(b: &mut test::Bencher) {
123+
const BYTES: usize = 128 * 1024;
124+
let src_path = temp_dir().join("uds-copy-bench-src");
125+
let mut src = OpenOptions::new()
126+
.create(true)
127+
.truncate(true)
128+
.read(true)
129+
.write(true)
130+
.open(src_path)
131+
.unwrap();
132+
src.write(&vec![0u8; BYTES]).unwrap();
133+
134+
let (mut sink, mut sink_drainer) = crate::os::unix::net::UnixStream::pair().unwrap();
135+
136+
crate::thread::spawn(move || {
137+
let mut sink_buf = vec![0u8; 1024 * 1024];
138+
loop {
139+
sink_drainer.read(&mut sink_buf[..]).unwrap();
140+
}
141+
});
142+
143+
b.bytes = BYTES as u64;
144+
b.iter(|| {
145+
src.seek(SeekFrom::Start(0)).unwrap();
146+
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
147+
});
148+
}
149+
121150
#[cfg(any(target_os = "linux", target_os = "android"))]
122151
#[bench]
123152
fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) {

0 commit comments

Comments
 (0)