1*7db6e063SLoGin use core::ops::BitAnd; 2*7db6e063SLoGin 37d66c313SLoGin use bitmap::{traits::BitMapOps, AllocBitmap}; 47d66c313SLoGin 5e2841179SLoGin use crate::{mm::percpu::PerCpu, smp::cpu::ProcessorId}; 67d66c313SLoGin 7e2841179SLoGin #[derive(Clone)] 87d66c313SLoGin pub struct CpuMask { 97d66c313SLoGin bmp: AllocBitmap, 107d66c313SLoGin } 117d66c313SLoGin 127d66c313SLoGin #[allow(dead_code)] 137d66c313SLoGin impl CpuMask { 147d66c313SLoGin pub fn new() -> Self { 15e2841179SLoGin let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM as usize); 167d66c313SLoGin Self { bmp } 177d66c313SLoGin } 187d66c313SLoGin 197d66c313SLoGin /// 获取CpuMask中的第一个cpu 20e2841179SLoGin pub fn first(&self) -> Option<ProcessorId> { 21e2841179SLoGin self.bmp 22e2841179SLoGin .first_index() 23e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 247d66c313SLoGin } 257d66c313SLoGin 267d66c313SLoGin /// 获取CpuMask中第一个未被置位的cpu 27e2841179SLoGin pub fn first_zero(&self) -> Option<ProcessorId> { 28e2841179SLoGin self.bmp 29e2841179SLoGin .first_false_index() 30e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 317d66c313SLoGin } 327d66c313SLoGin 337d66c313SLoGin /// 获取CpuMask中的最后一个被置位的cpu 34e2841179SLoGin pub fn last(&self) -> Option<ProcessorId> { 35e2841179SLoGin self.bmp 36e2841179SLoGin .last_index() 37e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 387d66c313SLoGin } 397d66c313SLoGin 407d66c313SLoGin /// 获取指定cpu之后第一个为1的位的cpu 41e2841179SLoGin pub fn next_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 42e2841179SLoGin self.bmp 43e2841179SLoGin .next_index(cpu.data() as usize) 44e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 457d66c313SLoGin } 467d66c313SLoGin 477d66c313SLoGin /// 获取指定cpu之后第一个为未被置位的cpu 48e2841179SLoGin pub fn next_zero_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 49e2841179SLoGin self.bmp 50e2841179SLoGin .next_false_index(cpu.data() as usize) 51e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 52e2841179SLoGin } 53e2841179SLoGin 54e2841179SLoGin pub fn set(&mut self, cpu: ProcessorId, value: bool) -> Option<bool> { 55e2841179SLoGin self.bmp.set(cpu.data() as usize, value) 56e2841179SLoGin } 57e2841179SLoGin 58e2841179SLoGin pub fn get(&self, cpu: ProcessorId) -> Option<bool> { 59e2841179SLoGin self.bmp.get(cpu.data() as usize) 60e2841179SLoGin } 61e2841179SLoGin 62e2841179SLoGin pub fn is_empty(&self) -> bool { 63e2841179SLoGin self.bmp.is_empty() 647d66c313SLoGin } 657d66c313SLoGin 667d66c313SLoGin /// 迭代所有被置位的cpu 677d66c313SLoGin pub fn iter_cpu(&self) -> CpuMaskIter { 687d66c313SLoGin CpuMaskIter { 697d66c313SLoGin mask: self, 708cb2e9b3SLoGin index: None, 717d66c313SLoGin set: true, 728cb2e9b3SLoGin begin: true, 737d66c313SLoGin } 747d66c313SLoGin } 757d66c313SLoGin 767d66c313SLoGin /// 迭代所有未被置位的cpu 777d66c313SLoGin pub fn iter_zero_cpu(&self) -> CpuMaskIter { 787d66c313SLoGin CpuMaskIter { 797d66c313SLoGin mask: self, 808cb2e9b3SLoGin index: None, 817d66c313SLoGin set: false, 828cb2e9b3SLoGin begin: true, 837d66c313SLoGin } 847d66c313SLoGin } 859430523bSyuyi2439 869430523bSyuyi2439 pub fn inner(&self) -> &AllocBitmap { 879430523bSyuyi2439 &self.bmp 889430523bSyuyi2439 } 897d66c313SLoGin } 907d66c313SLoGin 91*7db6e063SLoGin impl BitAnd for CpuMask { 92*7db6e063SLoGin type Output = Self; 93*7db6e063SLoGin 94*7db6e063SLoGin fn bitand(self, rhs: Self) -> Self::Output { 95*7db6e063SLoGin let bmp = self.bmp & rhs.bmp; 96*7db6e063SLoGin Self { bmp } 97*7db6e063SLoGin } 98*7db6e063SLoGin } 99*7db6e063SLoGin 1007d66c313SLoGin pub struct CpuMaskIter<'a> { 1017d66c313SLoGin mask: &'a CpuMask, 1028cb2e9b3SLoGin index: Option<ProcessorId>, 1037d66c313SLoGin set: bool, 1048cb2e9b3SLoGin begin: bool, 1057d66c313SLoGin } 1067d66c313SLoGin 1077d66c313SLoGin impl<'a> Iterator for CpuMaskIter<'a> { 108e2841179SLoGin type Item = ProcessorId; 1097d66c313SLoGin 110e2841179SLoGin fn next(&mut self) -> Option<ProcessorId> { 1118cb2e9b3SLoGin if self.index.is_none() && self.begin { 1127d66c313SLoGin if self.set { 1138cb2e9b3SLoGin self.index = self.mask.first(); 1147d66c313SLoGin } else { 1158cb2e9b3SLoGin self.index = self.mask.first_zero(); 1167d66c313SLoGin } 1177d66c313SLoGin 1188cb2e9b3SLoGin self.begin = false; 1197d66c313SLoGin } 1208cb2e9b3SLoGin let result = self.index; 1218cb2e9b3SLoGin if self.set { 1228cb2e9b3SLoGin self.index = self.mask.next_index(self.index?); 1238cb2e9b3SLoGin } else { 1248cb2e9b3SLoGin self.index = self.mask.next_zero_index(self.index?); 1258cb2e9b3SLoGin } 1268cb2e9b3SLoGin 1278cb2e9b3SLoGin result 1287d66c313SLoGin } 1297d66c313SLoGin } 130e2841179SLoGin 131e2841179SLoGin impl core::fmt::Debug for CpuMask { 132e2841179SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 133e2841179SLoGin f.debug_struct("CpuMask") 134e2841179SLoGin .field("bmp", &format!("size: {}", self.bmp.size())) 135e2841179SLoGin .finish() 136e2841179SLoGin } 137e2841179SLoGin } 138