Skip to content

Commit 9063eda

Browse files
committed
Move available_concurrency implementation to sys
1 parent 3824017 commit 9063eda

File tree

10 files changed

+194
-162
lines changed

10 files changed

+194
-162
lines changed

library/std/src/sys/hermit/thread.rs

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::ffi::CStr;
44
use crate::io;
55
use crate::mem;
6+
use crate::num::NonZeroUsize;
67
use crate::sys::hermit::abi;
78
use crate::sys::hermit::thread_local_dtor::run_dtors;
89
use crate::time::Duration;
@@ -95,6 +96,13 @@ impl Thread {
9596
}
9697
}
9798

99+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
100+
Err(io::Error::new_const(
101+
io::ErrorKind::NotFound,
102+
&"The number of hardware threads is not known for the target platform",
103+
))
104+
}
105+
98106
pub mod guard {
99107
pub type Guard = !;
100108
pub unsafe fn current() -> Option<Guard> {

library/std/src/sys/sgx/thread.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
22
use crate::ffi::CStr;
33
use crate::io;
4+
use crate::num::NonZeroUsize;
45
use crate::time::Duration;
56

67
use super::abi::usercalls;
@@ -135,6 +136,13 @@ impl Thread {
135136
}
136137
}
137138

139+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
140+
Err(io::Error::new_const(
141+
io::ErrorKind::NotFound,
142+
&"The number of hardware threads is not known for the target platform",
143+
))
144+
}
145+
138146
pub mod guard {
139147
pub type Guard = !;
140148
pub unsafe fn current() -> Option<Guard> {

library/std/src/sys/unix/thread.rs

+83
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::cmp;
22
use crate::ffi::CStr;
33
use crate::io;
44
use crate::mem;
5+
use crate::num::NonZeroUsize;
56
use crate::ptr;
67
use crate::sys::{os, stack_overflow};
78
use crate::time::Duration;
@@ -198,6 +199,88 @@ impl Drop for Thread {
198199
}
199200
}
200201

202+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
203+
cfg_if::cfg_if! {
204+
if #[cfg(any(
205+
target_os = "android",
206+
target_os = "emscripten",
207+
target_os = "fuchsia",
208+
target_os = "ios",
209+
target_os = "linux",
210+
target_os = "macos",
211+
target_os = "solaris",
212+
target_os = "illumos",
213+
))] {
214+
match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
215+
-1 => Err(io::Error::last_os_error()),
216+
0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
217+
cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
218+
}
219+
} else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
220+
use crate::ptr;
221+
222+
let mut cpus: libc::c_uint = 0;
223+
let mut cpus_size = crate::mem::size_of_val(&cpus);
224+
225+
unsafe {
226+
cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
227+
}
228+
229+
// Fallback approach in case of errors or no hardware threads.
230+
if cpus < 1 {
231+
let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
232+
let res = unsafe {
233+
libc::sysctl(
234+
mib.as_mut_ptr(),
235+
2,
236+
&mut cpus as *mut _ as *mut _,
237+
&mut cpus_size as *mut _ as *mut _,
238+
ptr::null_mut(),
239+
0,
240+
)
241+
};
242+
243+
// Handle errors if any.
244+
if res == -1 {
245+
return Err(io::Error::last_os_error());
246+
} else if cpus == 0 {
247+
return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
248+
}
249+
}
250+
Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
251+
} else if #[cfg(target_os = "openbsd")] {
252+
use crate::ptr;
253+
254+
let mut cpus: libc::c_uint = 0;
255+
let mut cpus_size = crate::mem::size_of_val(&cpus);
256+
let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
257+
258+
let res = unsafe {
259+
libc::sysctl(
260+
mib.as_mut_ptr(),
261+
2,
262+
&mut cpus as *mut _ as *mut _,
263+
&mut cpus_size as *mut _ as *mut _,
264+
ptr::null_mut(),
265+
0,
266+
)
267+
};
268+
269+
// Handle errors if any.
270+
if res == -1 {
271+
return Err(io::Error::last_os_error());
272+
} else if cpus == 0 {
273+
return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
274+
}
275+
276+
Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
277+
} else {
278+
// FIXME: implement on vxWorks, Redox, Haiku, l4re
279+
Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"))
280+
}
281+
}
282+
}
283+
201284
#[cfg(all(
202285
not(target_os = "linux"),
203286
not(target_os = "freebsd"),

library/std/src/sys/unsupported/thread.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::unsupported;
22
use crate::ffi::CStr;
33
use crate::io;
4+
use crate::num::NonZeroUsize;
45
use crate::time::Duration;
56

67
pub struct Thread(!);
@@ -30,6 +31,13 @@ impl Thread {
3031
}
3132
}
3233

34+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
35+
Err(io::Error::new_const(
36+
io::ErrorKind::NotFound,
37+
&"The number of hardware threads is not known for the target platform",
38+
))
39+
}
40+
3341
pub mod guard {
3442
pub type Guard = !;
3543
pub unsafe fn current() -> Option<Guard> {

library/std/src/sys/wasi/thread.rs

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::ffi::CStr;
44
use crate::io;
55
use crate::mem;
6+
use crate::num::NonZeroUsize;
67
use crate::sys::unsupported;
78
use crate::time::Duration;
89

@@ -63,6 +64,13 @@ impl Thread {
6364
}
6465
}
6566

67+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
68+
Err(io::Error::new_const(
69+
io::ErrorKind::NotFound,
70+
&"The number of hardware threads is not known for the target platform",
71+
))
72+
}
73+
6674
pub mod guard {
6775
pub type Guard = !;
6876
pub unsafe fn current() -> Option<Guard> {

library/std/src/sys/wasm/atomics/thread.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::ffi::CStr;
22
use crate::io;
3+
use crate::num::NonZeroUsize;
34
use crate::sys::unsupported;
45
use crate::time::Duration;
56

@@ -39,6 +40,13 @@ impl Thread {
3940
pub fn join(self) {}
4041
}
4142

43+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
44+
Err(io::Error::new_const(
45+
io::ErrorKind::NotFound,
46+
&"The number of hardware threads is not known for the target platform",
47+
))
48+
}
49+
4250
pub mod guard {
4351
pub type Guard = !;
4452
pub unsafe fn current() -> Option<Guard> {

library/std/src/sys/windows/c.rs

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use libc::{c_void, size_t, wchar_t};
1313
pub use self::EXCEPTION_DISPOSITION::*;
1414
pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
1515

16+
pub type DWORD_PTR = ULONG_PTR;
1617
pub type DWORD = c_ulong;
1718
pub type NonZeroDWORD = NonZero_c_ulong;
1819
pub type HANDLE = LPVOID;
@@ -53,6 +54,7 @@ pub type LPWSADATA = *mut WSADATA;
5354
pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
5455
pub type LPWSTR = *mut WCHAR;
5556
pub type LPFILETIME = *mut FILETIME;
57+
pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
5658
pub type LPWSABUF = *mut WSABUF;
5759
pub type LPWSAOVERLAPPED = *mut c_void;
5860
pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void;
@@ -533,6 +535,21 @@ pub struct FILETIME {
533535
pub dwHighDateTime: DWORD,
534536
}
535537

538+
#[repr(C)]
539+
pub struct SYSTEM_INFO {
540+
pub wProcessorArchitecture: WORD,
541+
pub wReserved: WORD,
542+
pub dwPageSize: DWORD,
543+
pub lpMinimumApplicationAddress: LPVOID,
544+
pub lpMaximumApplicationAddress: LPVOID,
545+
pub dwActiveProcessorMask: DWORD_PTR,
546+
pub dwNumberOfProcessors: DWORD,
547+
pub dwProcessorType: DWORD,
548+
pub dwAllocationGranularity: DWORD,
549+
pub wProcessorLevel: WORD,
550+
pub wProcessorRevision: WORD,
551+
}
552+
536553
#[repr(C)]
537554
pub struct OVERLAPPED {
538555
pub Internal: *mut c_ulong,
@@ -934,6 +951,7 @@ extern "system" {
934951
pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
935952

936953
pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
954+
pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
937955

938956
pub fn CreateEventW(
939957
lpEventAttributes: LPSECURITY_ATTRIBUTES,

library/std/src/sys/windows/thread.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::ffi::CStr;
22
use crate::io;
3+
use crate::num::NonZeroUsize;
34
use crate::ptr;
45
use crate::sys::c;
56
use crate::sys::handle::Handle;
@@ -98,6 +99,21 @@ impl Thread {
9899
}
99100
}
100101

102+
pub fn available_concurrency() -> io::Result<NonZeroUsize> {
103+
let res = unsafe {
104+
let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
105+
c::GetSystemInfo(&mut sysinfo);
106+
sysinfo.dwNumberOfProcessors as usize
107+
};
108+
match res {
109+
0 => Err(io::Error::new_const(
110+
io::ErrorKind::NotFound,
111+
&"The number of hardware threads is not known for the target platform",
112+
)),
113+
cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
114+
}
115+
}
116+
101117
#[cfg_attr(test, allow(dead_code))]
102118
pub mod guard {
103119
pub type Guard = !;

0 commit comments

Comments
 (0)