about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristiaan Dirkx <christiaan@dirkx.email>2021-04-29 11:40:14 +0200
committerChristiaan Dirkx <christiaan@dirkx.email>2021-06-21 11:01:46 +0200
commit9063edaf3bcf3d0897ee3e73b6468c3984883b18 (patch)
tree1b57b0dde3109e46a405a1353473a89a61fce447
parent3824017f8e57ce9dac6d69a1ce07f41c7034f82d (diff)
downloadrust-9063edaf3bcf3d0897ee3e73b6468c3984883b18.tar.gz
rust-9063edaf3bcf3d0897ee3e73b6468c3984883b18.zip
Move `available_concurrency` implementation to `sys`
-rw-r--r--library/std/src/sys/hermit/thread.rs8
-rw-r--r--library/std/src/sys/sgx/thread.rs8
-rw-r--r--library/std/src/sys/unix/thread.rs83
-rw-r--r--library/std/src/sys/unsupported/thread.rs8
-rw-r--r--library/std/src/sys/wasi/thread.rs8
-rw-r--r--library/std/src/sys/wasm/atomics/thread.rs8
-rw-r--r--library/std/src/sys/windows/c.rs18
-rw-r--r--library/std/src/sys/windows/thread.rs16
-rw-r--r--library/std/src/thread/available_concurrency.rs156
-rw-r--r--library/std/src/thread/mod.rs43
10 files changed, 194 insertions, 162 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 = !;
diff --git a/library/std/src/thread/available_concurrency.rs b/library/std/src/thread/available_concurrency.rs
deleted file mode 100644
index e8cdde88014..00000000000
--- a/library/std/src/thread/available_concurrency.rs
+++ /dev/null
@@ -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"))
-        }
-    }
-}
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 30d8c2a1b6f..f7e79141903 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -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()
+}