use libc::EINVAL;
use winapi::um::processthreadsapi::GetCurrentThread;
use winapi::um::winbase::SetThreadAffinityMask;
use super::errno_result;
use super::Error;
use super::Result;
pub fn set_cpu_affinity<I: IntoIterator<Item = usize>>(cpus: I) -> Result<usize> {
let mut affinity_mask: usize = 0;
for cpu in cpus {
if cpu >= 64 {
return Err(Error::new(EINVAL));
}
affinity_mask |= 1 << cpu;
}
set_cpu_affinity_mask(affinity_mask)
}
pub fn set_cpu_affinity_mask(affinity_mask: usize) -> Result<usize> {
let res: usize = unsafe {
let thread_handle = GetCurrentThread();
SetThreadAffinityMask(thread_handle, affinity_mask)
};
if res == 0 {
return errno_result::<usize>();
}
Ok(res)
}
pub fn get_cpu_affinity() -> Result<Vec<usize>> {
Err(Error::new(EINVAL))
}
#[cfg(test)]
mod tests {
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winbase::GetProcessAffinityMask;
use super::super::sched::*;
#[test]
fn cpu_affinity() {
let mut process_affinity_mask: usize = 0;
let mut system_affinity_mask: usize = 0;
let res = unsafe {
GetProcessAffinityMask(
GetCurrentProcess(),
&mut process_affinity_mask as *mut usize,
&mut system_affinity_mask as *mut usize,
)
};
assert_ne!(res, 0);
let mut prev_thread_affinity = set_cpu_affinity(vec![0, 1]).unwrap();
assert_eq!(process_affinity_mask, prev_thread_affinity);
prev_thread_affinity = set_cpu_affinity_mask(process_affinity_mask).unwrap();
assert_eq!(prev_thread_affinity, 3);
}
}