diff options
Diffstat (limited to 'library/std/src/sys/unix/thread.rs')
| -rw-r--r-- | library/std/src/sys/unix/thread.rs | 35 | 
1 files changed, 27 insertions, 8 deletions
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 2afec897a88..311ed95022f 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -216,7 +216,8 @@ impl Thread { target_os = "l4re", target_os = "emscripten", target_os = "redox", - target_os = "vxworks" + target_os = "vxworks", + target_os = "hurd", ))] pub fn set_name(_name: &CStr) { // Newlib, Emscripten, and VxWorks have no way to set a thread name. @@ -309,6 +310,7 @@ pub fn available_parallelism() -> io::Result<NonZeroUsize> { target_os = "android", target_os = "emscripten", target_os = "fuchsia", + target_os = "hurd", target_os = "ios", target_os = "tvos", target_os = "linux", @@ -316,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; @@ -692,6 +707,7 @@ mod cgroups { #[cfg(all( not(target_os = "linux"), not(target_os = "freebsd"), + not(target_os = "hurd"), not(target_os = "macos"), not(target_os = "netbsd"), not(target_os = "openbsd"), @@ -712,6 +728,7 @@ pub mod guard { #[cfg(any( target_os = "linux", target_os = "freebsd", + target_os = "hurd", target_os = "macos", target_os = "netbsd", target_os = "openbsd", @@ -768,6 +785,7 @@ pub mod guard { #[cfg(any( target_os = "android", target_os = "freebsd", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "l4re" @@ -905,6 +923,7 @@ pub mod guard { #[cfg(any( target_os = "android", target_os = "freebsd", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "l4re" @@ -936,7 +955,7 @@ pub mod guard { assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0); let stackaddr = stackptr.addr(); - ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd")) { + ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd", target_os = "hurd")) { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { Some(stackaddr - guardsize..stackaddr)  | 
