mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Rollup merge of #116038 - the8472:panic-on-sched_getaffinity-bug, r=cuviper
Fall back to _SC_NPROCESSORS_ONLN if sched_getaffinity returns an empty mask Followup to #115946 A gentler fix for #115868, one that doesn't panic, [suggested on zulip](https://rust-lang.zulipchat.com/#narrow/stream/259402-t-libs.2Fmeetings/topic/Meeting.202023-09-19/near/391942927) In that situation - on the buggy kernel versions - a zero-mask means no affinities have been set so `_SC_NPROCESSORS_ONLN` provides the right value.
This commit is contained in:
commit
faf13dd112
@ -318,25 +318,38 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> {
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
))] {
|
||||
#[allow(unused_assignments)]
|
||||
#[allow(unused_mut)]
|
||||
let mut quota = usize::MAX;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
{
|
||||
let quota = cgroups::quota().max(1);
|
||||
quota = cgroups::quota().max(1);
|
||||
let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
|
||||
unsafe {
|
||||
if libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) == 0 {
|
||||
let count = libc::CPU_COUNT(&set) as usize;
|
||||
let count = count.min(quota);
|
||||
// reported to occur on MIPS kernels older than our minimum supported kernel version for those targets
|
||||
let count = NonZeroUsize::new(count)
|
||||
.expect("CPU count must be > 0. This may be a bug in sched_getaffinity(); try upgrading the kernel.");
|
||||
return Ok(count);
|
||||
|
||||
// According to sched_getaffinity's API it should always be non-zero, but
|
||||
// some old MIPS kernels were buggy and zero-initialized the mask if
|
||||
// none was explicitly set.
|
||||
// In that case we use the sysconf fallback.
|
||||
if let Some(count) = NonZeroUsize::new(count) {
|
||||
return Ok(count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
|
||||
-1 => Err(io::Error::last_os_error()),
|
||||
0 => Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform")),
|
||||
cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
|
||||
cpus => {
|
||||
let count = cpus as usize;
|
||||
// Cover the unusual situation where we were able to get the quota but not the affinity mask
|
||||
let count = count.min(quota);
|
||||
Ok(unsafe { NonZeroUsize::new_unchecked(count) })
|
||||
}
|
||||
}
|
||||
} else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
|
||||
use crate::ptr;
|
||||
|
Loading…
Reference in New Issue
Block a user