Skip to content

Commit 9334ec9

Browse files
committed
Auto merge of #115228 - saethlin:is-interrupted, r=thomcc
Add a new helper to avoid calling io::Error::kind On `cfg(unix)`, `Error::kind` emits an enormous jump table that LLVM seems unable to optimize out. I don't really understand why, but see for yourself: https://godbolt.org/z/17hY496KG This change lets us check for `ErrorKind::Interrupted` without going through a big match. I've checked the codegen locally, and it has the desired effect on the codegen for `BufReader::read_exact`.
2 parents c503527 + 1abaf40 commit 9334ec9

File tree

12 files changed

+66
-7
lines changed

12 files changed

+66
-7
lines changed

library/std/src/fs.rs

+3
Original file line numberDiff line numberDiff line change
@@ -745,14 +745,17 @@ fn buffer_capacity_required(mut file: &File) -> Option<usize> {
745745

746746
#[stable(feature = "rust1", since = "1.0.0")]
747747
impl Read for &File {
748+
#[inline]
748749
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
749750
self.inner.read(buf)
750751
}
751752

753+
#[inline]
752754
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
753755
self.inner.read_vectored(bufs)
754756
}
755757

758+
#[inline]
756759
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
757760
self.inner.read_buf(cursor)
758761
}

library/std/src/io/error.rs

+10
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,16 @@ impl Error {
916916
ErrorData::SimpleMessage(m) => m.kind,
917917
}
918918
}
919+
920+
#[inline]
921+
pub(crate) fn is_interrupted(&self) -> bool {
922+
match self.repr.data() {
923+
ErrorData::Os(code) => sys::is_interrupted(code),
924+
ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
925+
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
926+
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
927+
}
928+
}
919929
}
920930

921931
impl fmt::Debug for Repr {

library/std/src/io/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
390390
let mut cursor = read_buf.unfilled();
391391
match r.read_buf(cursor.reborrow()) {
392392
Ok(()) => {}
393-
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
393+
Err(e) if e.is_interrupted() => continue,
394394
Err(e) => return Err(e),
395395
}
396396

@@ -421,7 +421,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
421421
buf.extend_from_slice(&probe[..n]);
422422
break;
423423
}
424-
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
424+
Err(ref e) if e.is_interrupted() => continue,
425425
Err(e) => return Err(e),
426426
}
427427
}
@@ -470,7 +470,7 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
470470
let tmp = buf;
471471
buf = &mut tmp[n..];
472472
}
473-
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
473+
Err(ref e) if e.is_interrupted() => {}
474474
Err(e) => return Err(e),
475475
}
476476
}
@@ -860,7 +860,7 @@ pub trait Read {
860860
let prev_written = cursor.written();
861861
match self.read_buf(cursor.reborrow()) {
862862
Ok(()) => {}
863-
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
863+
Err(e) if e.is_interrupted() => continue,
864864
Err(e) => return Err(e),
865865
}
866866

@@ -1579,7 +1579,7 @@ pub trait Write {
15791579
));
15801580
}
15811581
Ok(n) => buf = &buf[n..],
1582-
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
1582+
Err(ref e) if e.is_interrupted() => {}
15831583
Err(e) => return Err(e),
15841584
}
15851585
}
@@ -1943,7 +1943,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> R
19431943
let (done, used) = {
19441944
let available = match r.fill_buf() {
19451945
Ok(n) => n,
1946-
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
1946+
Err(ref e) if e.is_interrupted() => continue,
19471947
Err(e) => return Err(e),
19481948
};
19491949
match memchr::memchr(delim, available) {
@@ -2734,7 +2734,7 @@ impl<R: Read> Iterator for Bytes<R> {
27342734
return match self.inner.read(slice::from_mut(&mut byte)) {
27352735
Ok(0) => None,
27362736
Ok(..) => Some(Ok(byte)),
2737-
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
2737+
Err(ref e) if e.is_interrupted() => continue,
27382738
Err(e) => Some(Err(e)),
27392739
};
27402740
}

library/std/src/sys/itron/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
7979
}
8080
}
8181

82+
#[inline]
83+
pub fn is_interrupted(er: abi::ER) -> bool {
84+
er == abi::E_RLWAI
85+
}
86+
8287
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
8388
match er {
8489
// Success

library/std/src/sys/sgx/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
8686
}
8787
}
8888

89+
#[inline]
90+
pub fn is_interrupted(code: i32) -> bool {
91+
use fortanix_sgx_abi::Error;
92+
code == Error::Interrupted as _
93+
}
94+
8995
pub fn decode_error_kind(code: i32) -> ErrorKind {
9096
use fortanix_sgx_abi::Error;
9197

library/std/src/sys/solid/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
3131
}
3232
}
3333

34+
#[inline]
35+
fn is_interrupted(er: abi::ER) -> bool {
36+
false
37+
}
38+
3439
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
3540
match er {
3641
// Success

library/std/src/sys/solid/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ pub fn unsupported_err() -> crate::io::Error {
7272
)
7373
}
7474

75+
#[inline]
76+
pub fn is_interrupted(code: i32) -> bool {
77+
error::is_interrupted(code)
78+
}
79+
7580
pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
7681
error::decode_error_kind(code)
7782
}

library/std/src/sys/solid/net.rs

+6
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> {
181181
unsafe { CStr::from_ptr(netc::strerror(er)) }.to_str().ok()
182182
}
183183

184+
#[inline]
185+
pub fn is_interrupted(er: abi::ER) -> bool {
186+
let errno = netc::SOLID_NET_ERR_BASE - er;
187+
errno as libc::c_int == libc::EINTR
188+
}
189+
184190
pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
185191
let errno = netc::SOLID_NET_ERR_BASE - er;
186192
match errno as libc::c_int {

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

+5
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,11 @@ pub use crate::sys::android::signal;
240240
#[cfg(not(target_os = "android"))]
241241
pub use libc::signal;
242242

243+
#[inline]
244+
pub(crate) fn is_interrupted(errno: i32) -> bool {
245+
errno == libc::EINTR
246+
}
247+
243248
pub fn decode_error_kind(errno: i32) -> ErrorKind {
244249
use ErrorKind::*;
245250
match errno as libc::c_int {

library/std/src/sys/unsupported/common.rs

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ pub fn unsupported_err() -> std_io::Error {
2323
)
2424
}
2525

26+
pub fn is_interrupted(_code: i32) -> bool {
27+
false
28+
}
29+
2630
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
2731
crate::io::ErrorKind::Uncategorized
2832
}

library/std/src/sys/wasi/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ cfg_if::cfg_if! {
7676
mod common;
7777
pub use common::*;
7878

79+
#[inline]
80+
pub fn is_interrupted(errno: i32) -> bool {
81+
errno == wasi::ERRNO_INTR.raw().into()
82+
}
83+
7984
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
8085
use std_io::ErrorKind::*;
8186
if errno > u16::MAX as i32 || errno < 0 {

library/std/src/sys/windows/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ pub unsafe fn cleanup() {
6060
net::cleanup();
6161
}
6262

63+
#[inline]
64+
pub fn is_interrupted(_errno: i32) -> bool {
65+
false
66+
}
67+
6368
pub fn decode_error_kind(errno: i32) -> ErrorKind {
6469
use ErrorKind::*;
6570

0 commit comments

Comments
 (0)