Auto merge of #86527 - JohnTitor:rollup-cbu78g4, r=JohnTitor

Rollup of 11 pull requests

Successful merges:

 - #85054 (Revert SGX inline asm syntax)
 - #85182 (Move `available_concurrency` implementation to `sys`)
 - #86037 (Add `io::Cursor::{remaining, remaining_slice, is_empty}`)
 - #86114 (Reopen #79692 (Format symbols under shared frames))
 - #86297 (Allow to pass arguments to rustdoc-gui tool)
 - #86334 (Resolve type aliases to the type they point to in intra-doc links)
 - #86367 (Fix comment about rustc_inherit_overflow_checks in abs().)
 - #86381 (Add regression test for issue #39161)
 - #86387 (Remove `#[allow(unused_lifetimes)]` which is now unnecessary)
 - #86398 (Add regression test for issue #54685)
 - #86493 (Say "this enum variant takes"/"this struct takes" instead of "this function takes")

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2021-06-22 01:14:31 +00:00
30 changed files with 535 additions and 204 deletions

View File

@@ -1,156 +0,0 @@
use crate::io;
use crate::num::NonZeroUsize;
/// Returns the number of hardware threads available to the program.
///
/// This value should be considered only a hint.
///
/// # Platform-specific behavior
///
/// If interpreted as the number of actual hardware threads, it may undercount on
/// Windows systems with more than 64 hardware threads. If interpreted as the
/// available concurrency for that process, it may overcount on Windows systems
/// when limited by a process wide affinity mask or job object limitations, and
/// it may overcount on Linux systems when limited by a process wide affinity
/// mask or affected by cgroups limits.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not
/// limited to just these cases:
///
/// - If the number of hardware threads is not known for the target platform.
/// - The process lacks permissions to view the number of hardware threads
/// available.
///
/// # Examples
///
/// ```
/// # #![allow(dead_code)]
/// #![feature(available_concurrency)]
/// use std::thread;
///
/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1);
/// ```
#[unstable(feature = "available_concurrency", issue = "74479")]
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
available_concurrency_internal()
}
cfg_if::cfg_if! {
if #[cfg(windows)] {
#[allow(nonstandard_style)]
fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
#[repr(C)]
struct SYSTEM_INFO {
wProcessorArchitecture: u16,
wReserved: u16,
dwPageSize: u32,
lpMinimumApplicationAddress: *mut u8,
lpMaximumApplicationAddress: *mut u8,
dwActiveProcessorMask: *mut u8,
dwNumberOfProcessors: u32,
dwProcessorType: u32,
dwAllocationGranularity: u32,
wProcessorLevel: u16,
wProcessorRevision: u16,
}
extern "system" {
fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32;
}
let res = unsafe {
let mut sysinfo = crate::mem::zeroed();
GetSystemInfo(&mut sysinfo);
sysinfo.dwNumberOfProcessors as usize
};
match res {
0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
}
}
} else if #[cfg(any(
target_os = "android",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "illumos",
))] {
fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
-1 => Err(io::Error::last_os_error()),
0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
}
}
} else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
use crate::ptr;
let mut cpus: libc::c_uint = 0;
let mut cpus_size = crate::mem::size_of_val(&cpus);
unsafe {
cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
}
// Fallback approach in case of errors or no hardware threads.
if cpus < 1 {
let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
let res = unsafe {
libc::sysctl(
mib.as_mut_ptr(),
2,
&mut cpus as *mut _ as *mut _,
&mut cpus_size as *mut _ as *mut _,
ptr::null_mut(),
0,
)
};
// Handle errors if any.
if res == -1 {
return Err(io::Error::last_os_error());
} else if cpus == 0 {
return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
}
}
Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
}
} else if #[cfg(target_os = "openbsd")] {
fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
use crate::ptr;
let mut cpus: libc::c_uint = 0;
let mut cpus_size = crate::mem::size_of_val(&cpus);
let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
let res = unsafe {
libc::sysctl(
mib.as_mut_ptr(),
2,
&mut cpus as *mut _ as *mut _,
&mut cpus_size as *mut _ as *mut _,
ptr::null_mut(),
0,
)
};
// Handle errors if any.
if res == -1 {
return Err(io::Error::last_os_error());
} else if cpus == 0 {
return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
}
Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
}
} else {
// FIXME: implement on vxWorks, Redox, HermitCore, Haiku, l4re
fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"))
}
}
}

View File

@@ -155,6 +155,7 @@ use crate::fmt;
use crate::io;
use crate::mem;
use crate::num::NonZeroU64;
use crate::num::NonZeroUsize;
use crate::panic;
use crate::panicking;
use crate::str;
@@ -174,15 +175,9 @@ use crate::time::Duration;
#[macro_use]
mod local;
#[unstable(feature = "available_concurrency", issue = "74479")]
mod available_concurrency;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::local::{AccessError, LocalKey};
#[unstable(feature = "available_concurrency", issue = "74479")]
pub use available_concurrency::available_concurrency;
// The types used by the thread_local! macro to access TLS keys. Note that there
// are two types, the "OS" type and the "fast" type. The OS thread local key
// type is accessed via platform-specific API calls and is slow, while the fast
@@ -1422,3 +1417,39 @@ fn _assert_sync_and_send() {
_assert_both::<JoinHandle<()>>();
_assert_both::<Thread>();
}
/// Returns the number of hardware threads available to the program.
///
/// This value should be considered only a hint.
///
/// # Platform-specific behavior
///
/// If interpreted as the number of actual hardware threads, it may undercount on
/// Windows systems with more than 64 hardware threads. If interpreted as the
/// available concurrency for that process, it may overcount on Windows systems
/// when limited by a process wide affinity mask or job object limitations, and
/// it may overcount on Linux systems when limited by a process wide affinity
/// mask or affected by cgroups limits.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not
/// limited to just these cases:
///
/// - If the number of hardware threads is not known for the target platform.
/// - The process lacks permissions to view the number of hardware threads
/// available.
///
/// # Examples
///
/// ```
/// # #![allow(dead_code)]
/// #![feature(available_concurrency)]
/// use std::thread;
///
/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1);
/// ```
#[unstable(feature = "available_concurrency", issue = "74479")]
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
imp::available_concurrency()
}