2 use crate::num::NonZeroUsize;
4 /// Returns the number of hardware threads available to the program.
6 /// This value should be considered only a hint.
8 /// # Platform-specific behavior
10 /// If interpreted as the number of actual hardware threads, it may undercount on
11 /// Windows systems with more than 64 hardware threads. If interpreted as the
12 /// available concurrency for that process, it may overcount on Windows systems
13 /// when limited by a process wide affinity mask or job object limitations, and
14 /// it may overcount on Linux systems when limited by a process wide affinity
15 /// mask or affected by cgroups limits.
19 /// This function will return an error in the following situations, but is not
20 /// limited to just these cases:
22 /// - If the number of hardware threads is not known for the target platform.
23 /// - The process lacks permissions to view the number of hardware threads
29 /// # #![allow(dead_code)]
30 /// #![feature(available_concurrency)]
33 /// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1);
35 #[unstable(feature = "available_concurrency", issue = "74479")]
36 pub fn available_concurrency() -> io::Result<NonZeroUsize> {
37 available_concurrency_internal()
42 #[allow(nonstandard_style)]
43 fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
46 wProcessorArchitecture: u16,
49 lpMinimumApplicationAddress: *mut u8,
50 lpMaximumApplicationAddress: *mut u8,
51 dwActiveProcessorMask: *mut u8,
52 dwNumberOfProcessors: u32,
54 dwAllocationGranularity: u32,
56 wProcessorRevision: u16,
59 fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32;
62 let mut sysinfo = crate::mem::zeroed();
63 GetSystemInfo(&mut sysinfo);
64 sysinfo.dwNumberOfProcessors as usize
67 0 => Err(io::Error::new(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform")),
68 cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
72 target_os = "android",
73 target_os = "cloudabi",
74 target_os = "emscripten",
75 target_os = "fuchsia",
79 target_os = "solaris",
80 target_os = "illumos",
82 fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
83 match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
84 -1 => Err(io::Error::last_os_error()),
85 0 => Err(io::Error::new(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform")),
86 cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
89 } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
90 fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
93 let mut cpus: libc::c_uint = 0;
94 let mut cpus_size = crate::mem::size_of_val(&cpus);
97 cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
100 // Fallback approach in case of errors or no hardware threads.
102 let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
107 &mut cpus as *mut _ as *mut _,
108 &mut cpus_size as *mut _ as *mut _,
114 // Handle errors if any.
116 return Err(io::Error::last_os_error());
117 } else if cpus == 0 {
118 return Err(io::Error::new(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
121 Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
123 } else if #[cfg(target_os = "openbsd")] {
124 fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
127 let mut cpus: libc::c_uint = 0;
128 let mut cpus_size = crate::mem::size_of_val(&cpus);
129 let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
135 &mut cpus as *mut _ as *mut _,
136 &mut cpus_size as *mut _ as *mut _,
142 // Handle errors if any.
144 return Err(io::Error::last_os_error());
145 } else if cpus == 0 {
146 return Err(io::Error::new(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
149 Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
152 // FIXME: implement on vxWorks, Redox, HermitCore, Haiku, l4re
153 fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
154 Err(io::Error::new(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"))