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`.
This commit is contained in:
bors 2023-08-26 02:19:08 +00:00
commit 9334ec9354
12 changed files with 66 additions and 7 deletions

View file

@ -79,6 +79,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
}
}
#[inline]
pub fn is_interrupted(er: abi::ER) -> bool {
er == abi::E_RLWAI
}
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
match er {
// Success

View file

@ -86,6 +86,12 @@ pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
}
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
use fortanix_sgx_abi::Error;
code == Error::Interrupted as _
}
pub fn decode_error_kind(code: i32) -> ErrorKind {
use fortanix_sgx_abi::Error;

View file

@ -31,6 +31,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
}
}
#[inline]
fn is_interrupted(er: abi::ER) -> bool {
false
}
pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
match er {
// Success

View file

@ -72,6 +72,11 @@ pub fn unsupported_err() -> crate::io::Error {
)
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
error::is_interrupted(code)
}
pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
error::decode_error_kind(code)
}

View file

@ -181,6 +181,12 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> {
unsafe { CStr::from_ptr(netc::strerror(er)) }.to_str().ok()
}
#[inline]
pub fn is_interrupted(er: abi::ER) -> bool {
let errno = netc::SOLID_NET_ERR_BASE - er;
errno as libc::c_int == libc::EINTR
}
pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
let errno = netc::SOLID_NET_ERR_BASE - er;
match errno as libc::c_int {

View file

@ -240,6 +240,11 @@ pub use crate::sys::android::signal;
#[cfg(not(target_os = "android"))]
pub use libc::signal;
#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> ErrorKind {
use ErrorKind::*;
match errno as libc::c_int {

View file

@ -23,6 +23,10 @@ pub fn unsupported_err() -> std_io::Error {
)
}
pub fn is_interrupted(_code: i32) -> bool {
false
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}

View file

@ -76,6 +76,11 @@ cfg_if::cfg_if! {
mod common;
pub use common::*;
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == wasi::ERRNO_INTR.raw().into()
}
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind::*;
if errno > u16::MAX as i32 || errno < 0 {

View file

@ -60,6 +60,11 @@ pub unsafe fn cleanup() {
net::cleanup();
}
#[inline]
pub fn is_interrupted(_errno: i32) -> bool {
false
}
pub fn decode_error_kind(errno: i32) -> ErrorKind {
use ErrorKind::*;