diff options
| author | Christiaan Dirkx <christiaan@dirkx.email> | 2021-04-29 11:40:14 +0200 |
|---|---|---|
| committer | Christiaan Dirkx <christiaan@dirkx.email> | 2021-06-21 11:01:46 +0200 |
| commit | 9063edaf3bcf3d0897ee3e73b6468c3984883b18 (patch) | |
| tree | 1b57b0dde3109e46a405a1353473a89a61fce447 /library/std/src/sys | |
| parent | 3824017f8e57ce9dac6d69a1ce07f41c7034f82d (diff) | |
| download | rust-9063edaf3bcf3d0897ee3e73b6468c3984883b18.tar.gz rust-9063edaf3bcf3d0897ee3e73b6468c3984883b18.zip | |
Move `available_concurrency` implementation to `sys`
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/hermit/thread.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/thread.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread.rs | 83 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/thread.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/thread.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/wasm/atomics/thread.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/windows/c.rs | 18 | ||||
| -rw-r--r-- | library/std/src/sys/windows/thread.rs | 16 |
8 files changed, 157 insertions, 0 deletions
diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index f35a3a8a80f..3d00e626e1a 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -3,6 +3,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::sys::hermit::abi; use crate::sys::hermit::thread_local_dtor::run_dtors; use crate::time::Duration; @@ -95,6 +96,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs index 67e2e8b59d3..b82ae86521a 100644 --- a/library/std/src/sys/sgx/thread.rs +++ b/library/std/src/sys/sgx/thread.rs @@ -1,6 +1,7 @@ #![cfg_attr(test, allow(dead_code))] // why is this necessary? use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::time::Duration; use super::abi::usercalls; @@ -135,6 +136,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index b8f43caec32..e49971de940 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -2,6 +2,7 @@ use crate::cmp; use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::ptr; use crate::sys::{os, stack_overflow}; use crate::time::Duration; @@ -198,6 +199,88 @@ impl Drop for Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + cfg_if::cfg_if! { + 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", + ))] { + 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"))] { + 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")] { + 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, Haiku, l4re + Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")) + } + } +} + #[cfg(all( not(target_os = "linux"), not(target_os = "freebsd"), diff --git a/library/std/src/sys/unsupported/thread.rs b/library/std/src/sys/unsupported/thread.rs index cda8510e1ba..47005ead196 100644 --- a/library/std/src/sys/unsupported/thread.rs +++ b/library/std/src/sys/unsupported/thread.rs @@ -1,6 +1,7 @@ use super::unsupported; use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::time::Duration; pub struct Thread(!); @@ -30,6 +31,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs index 74515553a82..959077f7b54 100644 --- a/library/std/src/sys/wasi/thread.rs +++ b/library/std/src/sys/wasi/thread.rs @@ -3,6 +3,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::sys::unsupported; use crate::time::Duration; @@ -63,6 +64,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { diff --git a/library/std/src/sys/wasm/atomics/thread.rs b/library/std/src/sys/wasm/atomics/thread.rs index 54bc877aa7d..8207a41035d 100644 --- a/library/std/src/sys/wasm/atomics/thread.rs +++ b/library/std/src/sys/wasm/atomics/thread.rs @@ -1,5 +1,6 @@ use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::sys::unsupported; use crate::time::Duration; @@ -39,6 +40,13 @@ impl Thread { pub fn join(self) {} } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index b64870401f1..193c28c7673 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -13,6 +13,7 @@ use libc::{c_void, size_t, wchar_t}; pub use self::EXCEPTION_DISPOSITION::*; pub use self::FILE_INFO_BY_HANDLE_CLASS::*; +pub type DWORD_PTR = ULONG_PTR; pub type DWORD = c_ulong; pub type NonZeroDWORD = NonZero_c_ulong; pub type HANDLE = LPVOID; @@ -53,6 +54,7 @@ pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; +pub type LPSYSTEM_INFO = *mut SYSTEM_INFO; pub type LPWSABUF = *mut WSABUF; pub type LPWSAOVERLAPPED = *mut c_void; pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void; @@ -534,6 +536,21 @@ pub struct FILETIME { } #[repr(C)] +pub struct SYSTEM_INFO { + pub wProcessorArchitecture: WORD, + pub wReserved: WORD, + pub dwPageSize: DWORD, + pub lpMinimumApplicationAddress: LPVOID, + pub lpMaximumApplicationAddress: LPVOID, + pub dwActiveProcessorMask: DWORD_PTR, + pub dwNumberOfProcessors: DWORD, + pub dwProcessorType: DWORD, + pub dwAllocationGranularity: DWORD, + pub wProcessorLevel: WORD, + pub wProcessorRevision: WORD, +} + +#[repr(C)] pub struct OVERLAPPED { pub Internal: *mut c_ulong, pub InternalHigh: *mut c_ulong, @@ -934,6 +951,7 @@ extern "system" { pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME); + pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO); pub fn CreateEventW( lpEventAttributes: LPSECURITY_ATTRIBUTES, diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index 38839ea5e90..ef7a9733fd8 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -1,5 +1,6 @@ use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::ptr; use crate::sys::c; use crate::sys::handle::Handle; @@ -98,6 +99,21 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result<NonZeroUsize> { + let res = unsafe { + let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed(); + c::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) }), + } +} + #[cfg_attr(test, allow(dead_code))] pub mod guard { pub type Guard = !; |
