use super::CpuTopology;
#[cfg(windows)]
use super::ProcessorAffinityGroups;
use crate::topology::types::EfficiencyClass;
#[derive(Clone, Copy, Debug)]
pub struct CpuEfficiencyView<'topology> {
classes: &'topology [EfficiencyClass],
highest: EfficiencyClass,
}
impl<'topology> CpuEfficiencyView<'topology> {
pub(super) fn new(classes: &'topology [EfficiencyClass]) -> Option<Self> {
let highest = classes.iter().max().copied()?;
Some(Self { classes, highest })
}
#[must_use]
pub const fn classes(self) -> &'topology [EfficiencyClass] {
self.classes
}
#[must_use]
pub fn class_count(self) -> usize {
usize::from(self.highest.rank()) + 1
}
#[must_use]
pub fn is_hybrid(self) -> bool {
self.class_count() > 1
}
#[must_use]
pub const fn highest_class(self) -> EfficiencyClass {
self.highest
}
#[must_use]
pub fn processor_class(self, processor: u32) -> Option<EfficiencyClass> {
self.classes.get(usize::try_from(processor).ok()?).copied()
}
#[must_use]
pub fn is_in_highest_class(self, processor: u32) -> Option<bool> {
Some(self.processor_class(processor)? == self.highest)
}
#[must_use = "iterators are lazy; consume the returned processor iterator"]
pub fn processors_in_class(
self,
class: EfficiencyClass,
) -> impl Iterator<Item = u32> + 'topology {
self.classes
.iter()
.enumerate()
.filter(move |(_, candidate)| **candidate == class)
.filter_map(|(processor, _)| u32::try_from(processor).ok())
}
#[must_use = "iterators are lazy; consume the returned processor iterator"]
pub fn highest_class_processors(self) -> impl Iterator<Item = u32> + 'topology {
self.processors_in_class(self.highest)
}
#[cfg(windows)]
#[must_use]
pub fn processor_affinity_groups(self, class: EfficiencyClass) -> ProcessorAffinityGroups {
ProcessorAffinityGroups::from_processors(self.processors_in_class(class))
}
#[cfg(windows)]
#[must_use]
pub fn highest_class_affinity_groups(self) -> ProcessorAffinityGroups {
self.processor_affinity_groups(self.highest)
}
}
impl CpuTopology {
#[must_use]
pub fn efficiency(&self) -> Option<CpuEfficiencyView<'_>> {
CpuEfficiencyView::new(self.efficiency_classes.as_deref()?)
}
}