diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 631aedd26b4ea..f73d202a777ca 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -2477,11 +2477,11 @@ Windows.Win32.System.Pipes.PIPE_TYPE_BYTE Windows.Win32.System.Pipes.PIPE_TYPE_MESSAGE Windows.Win32.System.Pipes.PIPE_WAIT Windows.Win32.System.SystemInformation.GetSystemDirectoryW -Windows.Win32.System.SystemInformation.GetSystemInfo Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime Windows.Win32.System.SystemInformation.GetWindowsDirectoryW Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE Windows.Win32.System.SystemInformation.SYSTEM_INFO +Windows.Win32.System.SystemServices.ALL_PROCESSOR_GROUPS Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH Windows.Win32.System.SystemServices.DLL_THREAD_DETACH Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS @@ -2513,6 +2513,7 @@ Windows.Win32.System.Threading.DEBUG_PROCESS Windows.Win32.System.Threading.DETACHED_PROCESS Windows.Win32.System.Threading.ExitProcess Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT +Windows.Win32.System.Threading.GetActiveProcessorCount Windows.Win32.System.Threading.GetCurrentProcess Windows.Win32.System.Threading.GetCurrentProcessId Windows.Win32.System.Threading.GetCurrentThread diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 02377087173a7..ed5102c4b5c52 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -219,6 +219,10 @@ extern "system" { pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL; } #[link(name = "kernel32")] +extern "system" { + pub fn GetActiveProcessorCount(groupnumber: u16) -> u32; +} +#[link(name = "kernel32")] extern "system" { pub fn GetCommandLineW() -> PCWSTR; } @@ -338,10 +342,6 @@ extern "system" { pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32; } #[link(name = "kernel32")] -extern "system" { - pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO) -> (); -} -#[link(name = "kernel32")] extern "system" { pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> (); } @@ -822,6 +822,7 @@ impl ::core::clone::Clone for ADDRINFOA { pub const AF_INET: ADDRESS_FAMILY = 2u16; pub const AF_INET6: ADDRESS_FAMILY = 23u16; pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16; +pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32; #[repr(C)] pub union ARM64_NT_NEON128 { pub Anonymous: ARM64_NT_NEON128_0, diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index 18cecb65681d2..cb52404a03010 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -101,15 +101,13 @@ impl Thread { pub fn available_parallelism() -> io::Result { let res = unsafe { - let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed(); - c::GetSystemInfo(&mut sysinfo); - sysinfo.dwNumberOfProcessors as usize + // FIXME: windows::Win32::System::SystemServices::ALL_PROCESSOR_GROUPS should be u16, not u32 + // FIXME: if you need even more accurate result on 32-bit Windows with more, than 64 cores, + // consider implementing this using GetLogicalProcessorInformationEx + c::GetActiveProcessorCount(c::ALL_PROCESSOR_GROUPS as u16) as usize }; match res { - 0 => Err(io::const_io_error!( - io::ErrorKind::NotFound, - "The number of hardware threads is not known for the target platform", - )), + 0 => Err(io::Error::last_os_error()), cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }), } } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index cb90ed57ffe99..ba55b04ca6867 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -203,6 +203,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { )?; } + // Number of cores, but more accurate vaulue, than GetSystemInfo.dwNumberOfProcessors + // if number of cores > 64. If called with ALL_PROCESSOR_GROUPS as groupnumber, + // returns total number of cores, instead of number in group, see + // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getactiveprocessorcount + "GetActiveProcessorCount" => { + let [groupnumber] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.read_scalar(groupnumber)?.to_u16()?; + this.write_scalar(Scalar::from_u32(this.machine.num_cpus), dest)?; + } + // Thread-local storage "TlsAlloc" => { // This just creates a key; Windows does not natively support TLS destructors.