#[cfg(target_os = "windows")]
pub fn pin_to_p_cores() -> bool {
use windows::Win32::Foundation::HANDLE;
use windows::Win32::System::SystemInformation::{
GetLogicalProcessorInformationEx, RelationProcessorCore,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX,
};
use windows::Win32::System::Threading::{GetCurrentProcess, SetProcessAffinityMask};
let mut len: u32 = 0;
unsafe {
let _ = GetLogicalProcessorInformationEx(RelationProcessorCore, None, &mut len);
}
if len == 0 {
return false;
}
let mut buf: Vec<u8> = vec![0u8; len as usize];
let ok = unsafe {
GetLogicalProcessorInformationEx(
RelationProcessorCore,
Some(
buf.as_mut_ptr()
.cast::<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(),
),
&mut len,
)
};
if ok.is_err() {
return false;
}
let mut offset = 0usize;
let mut max_class: u8 = 0;
let mut entries: Vec<(u8, u64)> = Vec::new();
while offset < buf.len() {
let entry = unsafe {
&*(buf.as_ptr().add(offset) as *const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)
};
let size = entry.Size as usize;
if size == 0 {
break;
}
let core = unsafe { &entry.Anonymous.Processor };
let class = core.EfficiencyClass;
let mask = core.GroupMask[0].Mask as u64;
max_class = max_class.max(class);
entries.push((class, mask));
offset += size;
}
if entries.iter().all(|(class, _)| *class == entries[0].0) {
return false;
}
let p_core_mask: u64 = entries
.iter()
.filter(|(class, _)| *class == max_class)
.fold(0u64, |acc, (_, mask)| acc | mask);
if p_core_mask == 0 {
return false;
}
let handle: HANDLE = unsafe { GetCurrentProcess() };
unsafe { SetProcessAffinityMask(handle, p_core_mask as usize) }.is_ok()
}
#[cfg(not(target_os = "windows"))]
pub fn pin_to_p_cores() -> bool {
false
}