17d66c313SLoGin use bitmap::{traits::BitMapOps, AllocBitmap}; 27d66c313SLoGin 3*e2841179SLoGin use crate::{mm::percpu::PerCpu, smp::cpu::ProcessorId}; 47d66c313SLoGin 5*e2841179SLoGin #[derive(Clone)] 67d66c313SLoGin pub struct CpuMask { 77d66c313SLoGin bmp: AllocBitmap, 87d66c313SLoGin } 97d66c313SLoGin 107d66c313SLoGin #[allow(dead_code)] 117d66c313SLoGin impl CpuMask { 127d66c313SLoGin pub fn new() -> Self { 13*e2841179SLoGin let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM as usize); 147d66c313SLoGin Self { bmp } 157d66c313SLoGin } 167d66c313SLoGin 177d66c313SLoGin /// 获取CpuMask中的第一个cpu 18*e2841179SLoGin pub fn first(&self) -> Option<ProcessorId> { 19*e2841179SLoGin self.bmp 20*e2841179SLoGin .first_index() 21*e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 227d66c313SLoGin } 237d66c313SLoGin 247d66c313SLoGin /// 获取CpuMask中第一个未被置位的cpu 25*e2841179SLoGin pub fn first_zero(&self) -> Option<ProcessorId> { 26*e2841179SLoGin self.bmp 27*e2841179SLoGin .first_false_index() 28*e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 297d66c313SLoGin } 307d66c313SLoGin 317d66c313SLoGin /// 获取CpuMask中的最后一个被置位的cpu 32*e2841179SLoGin pub fn last(&self) -> Option<ProcessorId> { 33*e2841179SLoGin self.bmp 34*e2841179SLoGin .last_index() 35*e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 367d66c313SLoGin } 377d66c313SLoGin 387d66c313SLoGin /// 获取指定cpu之后第一个为1的位的cpu 39*e2841179SLoGin pub fn next_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 40*e2841179SLoGin self.bmp 41*e2841179SLoGin .next_index(cpu.data() as usize) 42*e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 437d66c313SLoGin } 447d66c313SLoGin 457d66c313SLoGin /// 获取指定cpu之后第一个为未被置位的cpu 46*e2841179SLoGin pub fn next_zero_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 47*e2841179SLoGin self.bmp 48*e2841179SLoGin .next_false_index(cpu.data() as usize) 49*e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 50*e2841179SLoGin } 51*e2841179SLoGin 52*e2841179SLoGin pub fn set(&mut self, cpu: ProcessorId, value: bool) -> Option<bool> { 53*e2841179SLoGin self.bmp.set(cpu.data() as usize, value) 54*e2841179SLoGin } 55*e2841179SLoGin 56*e2841179SLoGin pub fn get(&self, cpu: ProcessorId) -> Option<bool> { 57*e2841179SLoGin self.bmp.get(cpu.data() as usize) 58*e2841179SLoGin } 59*e2841179SLoGin 60*e2841179SLoGin pub fn is_empty(&self) -> bool { 61*e2841179SLoGin self.bmp.is_empty() 627d66c313SLoGin } 637d66c313SLoGin 647d66c313SLoGin /// 迭代所有被置位的cpu 657d66c313SLoGin pub fn iter_cpu(&self) -> CpuMaskIter { 667d66c313SLoGin CpuMaskIter { 677d66c313SLoGin mask: self, 68*e2841179SLoGin index: ProcessorId::new(0), 697d66c313SLoGin set: true, 707d66c313SLoGin } 717d66c313SLoGin } 727d66c313SLoGin 737d66c313SLoGin /// 迭代所有未被置位的cpu 747d66c313SLoGin pub fn iter_zero_cpu(&self) -> CpuMaskIter { 757d66c313SLoGin CpuMaskIter { 767d66c313SLoGin mask: self, 77*e2841179SLoGin index: ProcessorId::new(0), 787d66c313SLoGin set: false, 797d66c313SLoGin } 807d66c313SLoGin } 817d66c313SLoGin } 827d66c313SLoGin 837d66c313SLoGin pub struct CpuMaskIter<'a> { 847d66c313SLoGin mask: &'a CpuMask, 85*e2841179SLoGin index: ProcessorId, 867d66c313SLoGin set: bool, 877d66c313SLoGin } 887d66c313SLoGin 897d66c313SLoGin impl<'a> Iterator for CpuMaskIter<'a> { 90*e2841179SLoGin type Item = ProcessorId; 917d66c313SLoGin 92*e2841179SLoGin fn next(&mut self) -> Option<ProcessorId> { 93*e2841179SLoGin if self.index.data() == 0 { 947d66c313SLoGin if self.set { 957d66c313SLoGin self.index = self.mask.first()?; 967d66c313SLoGin } else { 977d66c313SLoGin self.index = self.mask.first_zero()?; 987d66c313SLoGin } 997d66c313SLoGin } 1007d66c313SLoGin 1017d66c313SLoGin if self.set { 1027d66c313SLoGin self.index = self.mask.next_index(self.index)?; 1037d66c313SLoGin } else { 1047d66c313SLoGin self.index = self.mask.next_zero_index(self.index)?; 1057d66c313SLoGin } 1067d66c313SLoGin Some(self.index) 1077d66c313SLoGin } 1087d66c313SLoGin } 109*e2841179SLoGin 110*e2841179SLoGin impl core::fmt::Debug for CpuMask { 111*e2841179SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 112*e2841179SLoGin f.debug_struct("CpuMask") 113*e2841179SLoGin .field("bmp", &format!("size: {}", self.bmp.size())) 114*e2841179SLoGin .finish() 115*e2841179SLoGin } 116*e2841179SLoGin } 117