Skip to main content

themis/topology/cpu/
efficiency_view.rs

1//! Borrowed, presence-proven CPU efficiency-class queries.
2
3use super::CpuTopology;
4#[cfg(windows)]
5use super::ProcessorAffinityGroups;
6use crate::topology::types::EfficiencyClass;
7
8/// A borrowed CPU efficiency-class table whose presence is already proven.
9///
10/// Construct this view through [`CpuTopology::efficiency`]. Its class-level
11/// queries are total because the optional platform report has been discharged
12/// once at the boundary. Processor-index queries remain optional because an
13/// index can lie outside the snapshot.
14#[derive(Clone, Copy, Debug)]
15pub struct CpuEfficiencyView<'topology> {
16    classes: &'topology [EfficiencyClass],
17    highest: EfficiencyClass,
18}
19
20impl<'topology> CpuEfficiencyView<'topology> {
21    pub(super) fn new(classes: &'topology [EfficiencyClass]) -> Option<Self> {
22        let highest = classes.iter().max().copied()?;
23        Some(Self { classes, highest })
24    }
25
26    /// Returns the per-processor dense efficiency ranks.
27    #[must_use]
28    pub const fn classes(self) -> &'topology [EfficiencyClass] {
29        self.classes
30    }
31
32    /// Returns how many distinct efficiency classes are represented.
33    #[must_use]
34    pub fn class_count(self) -> usize {
35        usize::from(self.highest.rank()) + 1
36    }
37
38    /// Returns whether more than one efficiency class is represented.
39    #[must_use]
40    pub fn is_hybrid(self) -> bool {
41        self.class_count() > 1
42    }
43
44    /// Returns the most performant represented class.
45    #[must_use]
46    pub const fn highest_class(self) -> EfficiencyClass {
47        self.highest
48    }
49
50    /// Returns the represented class of one processor.
51    ///
52    /// `None` means `processor` lies outside this topology snapshot; class
53    /// presence itself was proven when this view was constructed.
54    #[must_use]
55    pub fn processor_class(self, processor: u32) -> Option<EfficiencyClass> {
56        self.classes.get(usize::try_from(processor).ok()?).copied()
57    }
58
59    /// Returns whether one processor belongs to the highest represented class.
60    ///
61    /// `None` means `processor` lies outside this topology snapshot.
62    #[must_use]
63    pub fn is_in_highest_class(self, processor: u32) -> Option<bool> {
64        Some(self.processor_class(processor)? == self.highest)
65    }
66
67    /// Iterates processors in `class` by ascending logical id.
68    #[must_use = "iterators are lazy; consume the returned processor iterator"]
69    pub fn processors_in_class(
70        self,
71        class: EfficiencyClass,
72    ) -> impl Iterator<Item = u32> + 'topology {
73        self.classes
74            .iter()
75            .enumerate()
76            .filter(move |(_, candidate)| **candidate == class)
77            // Every construction path caps the table below `u32::MAX`.
78            .filter_map(|(processor, _)| u32::try_from(processor).ok())
79    }
80
81    /// Iterates processors in the highest represented class.
82    #[must_use = "iterators are lazy; consume the returned processor iterator"]
83    pub fn highest_class_processors(self) -> impl Iterator<Item = u32> + 'topology {
84        self.processors_in_class(self.highest)
85    }
86
87    /// Builds group-partitioned native affinity masks for one class.
88    #[cfg(windows)]
89    #[must_use]
90    pub fn processor_affinity_groups(self, class: EfficiencyClass) -> ProcessorAffinityGroups {
91        ProcessorAffinityGroups::from_processors(self.processors_in_class(class))
92    }
93
94    /// Builds group-partitioned native masks for the highest represented class.
95    #[cfg(windows)]
96    #[must_use]
97    pub fn highest_class_affinity_groups(self) -> ProcessorAffinityGroups {
98        self.processor_affinity_groups(self.highest)
99    }
100}
101
102impl CpuTopology {
103    /// Returns a presence-proven view of reported CPU efficiency classes.
104    ///
105    /// `None` preserves platform absence. Once this returns `Some`, class count,
106    /// hybrid status, the highest class, and its processors are total
107    /// operations on the borrowed snapshot. Windows additionally exposes
108    /// group-aware native affinity masks through the returned view.
109    #[must_use]
110    pub fn efficiency(&self) -> Option<CpuEfficiencyView<'_>> {
111        CpuEfficiencyView::new(self.efficiency_classes.as_deref()?)
112    }
113}