1*7d66c313SLoGin use bitmap::{traits::BitMapOps, AllocBitmap}; 2*7d66c313SLoGin 3*7d66c313SLoGin use crate::mm::percpu::PerCpu; 4*7d66c313SLoGin 5*7d66c313SLoGin pub struct CpuMask { 6*7d66c313SLoGin bmp: AllocBitmap, 7*7d66c313SLoGin } 8*7d66c313SLoGin 9*7d66c313SLoGin #[allow(dead_code)] 10*7d66c313SLoGin impl CpuMask { 11*7d66c313SLoGin pub fn new() -> Self { 12*7d66c313SLoGin let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM); 13*7d66c313SLoGin Self { bmp } 14*7d66c313SLoGin } 15*7d66c313SLoGin 16*7d66c313SLoGin /// 获取CpuMask中的第一个cpu 17*7d66c313SLoGin pub fn first(&self) -> Option<usize> { 18*7d66c313SLoGin self.bmp.first_index() 19*7d66c313SLoGin } 20*7d66c313SLoGin 21*7d66c313SLoGin /// 获取CpuMask中第一个未被置位的cpu 22*7d66c313SLoGin pub fn first_zero(&self) -> Option<usize> { 23*7d66c313SLoGin self.bmp.first_false_index() 24*7d66c313SLoGin } 25*7d66c313SLoGin 26*7d66c313SLoGin /// 获取CpuMask中的最后一个被置位的cpu 27*7d66c313SLoGin pub fn last(&self) -> Option<usize> { 28*7d66c313SLoGin self.bmp.last_index() 29*7d66c313SLoGin } 30*7d66c313SLoGin 31*7d66c313SLoGin /// 获取指定cpu之后第一个为1的位的cpu 32*7d66c313SLoGin pub fn next_index(&self, cpu: usize) -> Option<usize> { 33*7d66c313SLoGin self.bmp.next_index(cpu) 34*7d66c313SLoGin } 35*7d66c313SLoGin 36*7d66c313SLoGin /// 获取指定cpu之后第一个为未被置位的cpu 37*7d66c313SLoGin pub fn next_zero_index(&self, cpu: usize) -> Option<usize> { 38*7d66c313SLoGin self.bmp.next_false_index(cpu) 39*7d66c313SLoGin } 40*7d66c313SLoGin 41*7d66c313SLoGin /// 迭代所有被置位的cpu 42*7d66c313SLoGin pub fn iter_cpu(&self) -> CpuMaskIter { 43*7d66c313SLoGin CpuMaskIter { 44*7d66c313SLoGin mask: self, 45*7d66c313SLoGin index: 0, 46*7d66c313SLoGin set: true, 47*7d66c313SLoGin } 48*7d66c313SLoGin } 49*7d66c313SLoGin 50*7d66c313SLoGin /// 迭代所有未被置位的cpu 51*7d66c313SLoGin pub fn iter_zero_cpu(&self) -> CpuMaskIter { 52*7d66c313SLoGin CpuMaskIter { 53*7d66c313SLoGin mask: self, 54*7d66c313SLoGin index: 0, 55*7d66c313SLoGin set: false, 56*7d66c313SLoGin } 57*7d66c313SLoGin } 58*7d66c313SLoGin } 59*7d66c313SLoGin 60*7d66c313SLoGin pub struct CpuMaskIter<'a> { 61*7d66c313SLoGin mask: &'a CpuMask, 62*7d66c313SLoGin index: usize, 63*7d66c313SLoGin set: bool, 64*7d66c313SLoGin } 65*7d66c313SLoGin 66*7d66c313SLoGin impl<'a> Iterator for CpuMaskIter<'a> { 67*7d66c313SLoGin type Item = usize; 68*7d66c313SLoGin 69*7d66c313SLoGin fn next(&mut self) -> Option<Self::Item> { 70*7d66c313SLoGin if self.index == 0 { 71*7d66c313SLoGin if self.set { 72*7d66c313SLoGin self.index = self.mask.first()?; 73*7d66c313SLoGin } else { 74*7d66c313SLoGin self.index = self.mask.first_zero()?; 75*7d66c313SLoGin } 76*7d66c313SLoGin } 77*7d66c313SLoGin 78*7d66c313SLoGin if self.set { 79*7d66c313SLoGin self.index = self.mask.next_index(self.index)?; 80*7d66c313SLoGin } else { 81*7d66c313SLoGin self.index = self.mask.next_zero_index(self.index)?; 82*7d66c313SLoGin } 83*7d66c313SLoGin Some(self.index) 84*7d66c313SLoGin } 85*7d66c313SLoGin } 86