Skip to content

Commit 0bd5c99

Browse files
committed
Implementation working
1 parent 82f43c2 commit 0bd5c99

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

src/windows/mod.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ use windows::{
1010
core::PSTR, Win32::System::Power::GetSystemPowerStatus,
1111
Win32::System::Power::SYSTEM_POWER_STATUS,
1212
Win32::System::SystemInformation::GetComputerNameExA,
13+
Win32::System::SystemInformation::GetLogicalProcessorInformation,
1314
Win32::System::SystemInformation::GetTickCount64,
1415
Win32::System::SystemInformation::GlobalMemoryStatusEx,
1516
Win32::System::SystemInformation::MEMORYSTATUSEX,
17+
Win32::System::SystemInformation::RelationProcessorCore,
1618
Win32::System::WindowsProgramming::GetUserNameA,
1719
};
1820

@@ -295,11 +297,76 @@ impl GeneralReadout for WindowsGeneralReadout {
295297
}
296298

297299
fn cpu_physical_cores(&self) -> Result<usize, ReadoutError> {
298-
Err(ReadoutError::NotImplemented)
300+
// Source: https://github.com/seanmonstar/num_cpus/blob/master/src/lib.rs#L129
301+
#[allow(non_camel_case_types, dead_code)]
302+
struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
303+
mask: usize,
304+
relationship: u32,
305+
_unused: [u64; 2]
306+
}
307+
308+
// The required size of the buffer, in bytes
309+
let mut needed_size = 0;
310+
311+
// Get the required size of the buffer
312+
unsafe {
313+
GetLogicalProcessorInformation(std::ptr::null_mut(), &mut needed_size);
314+
}
315+
316+
let struct_size = std::mem::size_of::<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>() as u32;
317+
318+
// Could be 0, or some other bogus size
319+
if needed_size == 0 || needed_size < struct_size || needed_size % struct_size != 0 {
320+
return Err(ReadoutError::Other(
321+
"Call to \"GetLogicalProcessorInformation\" returned an invalid size.".to_string()
322+
));
323+
}
324+
325+
let count = needed_size / struct_size;
326+
327+
// Allocate some memory where we will store the processor info
328+
let mut buf = Vec::with_capacity(count as usize);
329+
330+
let result;
331+
332+
// Populate the buffer with processor information
333+
unsafe {
334+
result = GetLogicalProcessorInformation(buf.as_mut_ptr(), &mut needed_size);
335+
}
336+
337+
// If failed for some reason
338+
if result.as_bool() == false {
339+
return Err(ReadoutError::Other(
340+
"Call to \"GetLogicalProcessorInformation\" failed.".to_string()
341+
))?;
342+
}
343+
344+
// Number of logical processor entries
345+
let count = needed_size / struct_size;
346+
347+
unsafe {
348+
buf.set_len(count as usize);
349+
}
350+
351+
let phys_proc_count = buf.iter()
352+
// Only interested in processor packages (physical processors.)
353+
.filter(|proc_info| proc_info.Relationship == RelationProcessorCore)
354+
.count();
355+
356+
return if phys_proc_count == 0 {
357+
Err(ReadoutError::Other(
358+
"No physical processor cores found.".to_string()
359+
))?
360+
} else {
361+
Ok(phys_proc_count)
362+
}
299363
}
300364

301365
fn cpu_cores(&self) -> Result<usize, ReadoutError> {
302-
Err(ReadoutError::NotImplemented)
366+
// Open the registry key containing the CPUs information.
367+
let cpu_info = RegKey::predef(HKEY_LOCAL_MACHINE).open_subkey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor")?;
368+
// Count the number of subkeys, which is the number of CPU logical processors.
369+
Ok(cpu_info.enum_keys().count())
303370
}
304371

305372
fn uptime(&self) -> Result<usize, ReadoutError> {

0 commit comments

Comments
 (0)