use crate::pal::ProcessorImpl;
use crate::pal::windows::{ProcessorGroupIndex, ProcessorIndexInGroup};
#[derive(Debug)]
pub(crate) struct GroupMask {
mask: usize,
group: Option<ProcessorGroupIndex>,
}
impl GroupMask {
pub(crate) fn none() -> Self {
Self {
mask: 0,
group: None,
}
}
pub(crate) fn from_components(mask: usize, group_index: ProcessorGroupIndex) -> Self {
Self {
mask,
group: Some(group_index),
}
}
pub(crate) fn value(&self) -> usize {
self.mask
}
pub(crate) fn contains_by_index_in_group(&self, index: ProcessorIndexInGroup) -> bool {
self.mask & (1 << usize::from(index)) != 0
}
#[cfg_attr(test, mutants::skip)] pub(crate) fn add(&mut self, p: &ProcessorImpl) {
if let Some(group) = self.group {
assert_eq!(
group, p.group_index,
"adding processors from different groups to the same mask is nonsense"
);
} else {
self.group = Some(p.group_index);
}
self.mask |= 1 << usize::from(p.index_in_group);
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
use crate::EfficiencyClass;
#[test]
fn smoke_test() {
let mut mask = GroupMask::none();
assert_eq!(mask.value(), 0);
let p0 = ProcessorImpl::new(0, 0, 0, 0, EfficiencyClass::Performance);
let p7 = ProcessorImpl::new(0, 7, 7, 0, EfficiencyClass::Performance);
mask.add(&p0);
assert_eq!(mask.value(), 1 << 0);
mask.add(&p7);
assert_eq!(mask.value(), (1 << 0) | (1 << 7));
let mut mask = GroupMask::none();
let p0_g1 = ProcessorImpl::new(1, 0, 1, 0, EfficiencyClass::Performance);
mask.add(&p0_g1);
assert_eq!(mask.value(), 1 << 0);
}
#[test]
#[should_panic]
fn wrong_group_is_panic() {
let mut mask = GroupMask::none();
assert_eq!(mask.value(), 0);
let p_g0 = ProcessorImpl::new(0, 0, 0, 0, EfficiencyClass::Performance);
let p_g1 = ProcessorImpl::new(1, 0, 1, 0, EfficiencyClass::Performance);
mask.add(&p_g0);
mask.add(&p_g1);
}
#[test]
fn from_components() {
let mask_value = (1 << 0) | (1 << 3) | (1 << 7);
let group_index = 2;
let mask = GroupMask::from_components(mask_value, group_index);
assert_eq!(mask.value(), mask_value);
assert_eq!(mask.group, Some(group_index));
}
#[test]
fn contains_by_index_in_group() {
let mut mask = GroupMask::none();
let p0 = ProcessorImpl::new(0, 0, 0, 0, EfficiencyClass::Performance);
let p3 = ProcessorImpl::new(0, 3, 3, 0, EfficiencyClass::Performance);
let p7 = ProcessorImpl::new(0, 7, 7, 0, EfficiencyClass::Performance);
mask.add(&p0);
mask.add(&p3);
mask.add(&p7);
assert!(mask.contains_by_index_in_group(0));
assert!(mask.contains_by_index_in_group(3));
assert!(mask.contains_by_index_in_group(7));
assert!(!mask.contains_by_index_in_group(1));
assert!(!mask.contains_by_index_in_group(2));
assert!(!mask.contains_by_index_in_group(4));
assert!(!mask.contains_by_index_in_group(8));
}
}