use crate::{
cpu::cpuset::CpuSet,
errors::{self, RawHwlocError},
ffi::int,
topology::Topology,
};
#[allow(unused)]
#[cfg(test)]
use similar_asserts::assert_eq;
use std::{ffi::c_uint, iter::FusedIterator, num::NonZeroUsize};
impl Topology {
#[allow(clippy::missing_errors_doc)]
#[doc(alias = "hwloc_windows_get_nr_processor_groups")]
pub fn num_processor_groups(&self) -> Result<NonZeroUsize, RawHwlocError> {
let count =
errors::call_hwloc_positive_or_minus1("hwloc_windows_get_nr_processor_groups", || unsafe {
hwlocality_sys::hwloc_windows_get_nr_processor_groups(self.as_ptr(), 0)
})?;
let count = NonZeroUsize::new(int::expect_usize(count))
.expect("Unexpected 0 processor group count");
Ok(count)
}
#[allow(clippy::missing_errors_doc)]
#[doc(alias = "hwloc_windows_get_processor_group_cpuset")]
pub fn processor_groups(
&self,
) -> Result<
impl DoubleEndedIterator<Item = Result<CpuSet, RawHwlocError>>
+ Clone
+ ExactSizeIterator
+ FusedIterator
+ '_,
RawHwlocError,
> {
Ok(
(0..usize::from(self.num_processor_groups()?)).map(|pg_index| {
let mut set = CpuSet::new();
let pg_index = c_uint::try_from(pg_index)
.expect("Can't fail, pg_index upper bound comes from hwloc");
errors::call_hwloc_zero_or_minus1(
"hwloc_windows_get_processor_group_cpuset",
|| unsafe {
hwlocality_sys::hwloc_windows_get_processor_group_cpuset(
self.as_ptr(),
pg_index,
set.as_mut_ptr(),
0,
)
},
)?;
Ok(set)
}),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[allow(unused)]
use similar_asserts::assert_eq;
#[test]
fn processor_groups() {
let topology = Topology::test_instance();
let expected_num_groups = topology.num_processor_groups().unwrap();
let mut actual_num_groups = 0;
let mut cpuset_union = CpuSet::new();
for group_cpuset in topology.processor_groups().unwrap() {
cpuset_union |= group_cpuset.unwrap();
actual_num_groups += 1;
}
assert_eq!(expected_num_groups.get(), actual_num_groups);
assert!(cpuset_union.includes(topology.cpuset()));
assert!(topology.complete_cpuset().includes(&cpuset_union));
}
}