17db6e063SLoGin use core::ops::BitAnd; 27db6e063SLoGin 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 { new() -> Self147d66c313SLoGin pub fn new() -> Self { 15e2841179SLoGin let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM as usize); 167d66c313SLoGin Self { bmp } 177d66c313SLoGin } 187d66c313SLoGin 19*0102d69fSLoGin /// # from_cpu - 从指定的CPU创建CPU掩码 20*0102d69fSLoGin /// 21*0102d69fSLoGin /// 该函数用于根据给定的CPU标识创建一个CPU掩码,只有指定的CPU被设置为激活状态。 22*0102d69fSLoGin /// 23*0102d69fSLoGin /// ## 参数 24*0102d69fSLoGin /// - `cpu`: `ProcessorId`,指定要设置为激活状态的CPU。 25*0102d69fSLoGin /// 26*0102d69fSLoGin /// ## 返回值 27*0102d69fSLoGin /// - `Self`: 返回一个新的`CpuMask`实例,其中只有指定的CPU被设置为激活状态。 from_cpu(cpu: ProcessorId) -> Self28*0102d69fSLoGin pub fn from_cpu(cpu: ProcessorId) -> Self { 29*0102d69fSLoGin let mut mask = Self::new(); 30*0102d69fSLoGin mask.set(cpu, true); 31*0102d69fSLoGin mask 32*0102d69fSLoGin } 33*0102d69fSLoGin 347d66c313SLoGin /// 获取CpuMask中的第一个cpu first(&self) -> Option<ProcessorId>35e2841179SLoGin pub fn first(&self) -> Option<ProcessorId> { 36e2841179SLoGin self.bmp 37e2841179SLoGin .first_index() 38e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 397d66c313SLoGin } 407d66c313SLoGin 417d66c313SLoGin /// 获取CpuMask中第一个未被置位的cpu first_zero(&self) -> Option<ProcessorId>42e2841179SLoGin pub fn first_zero(&self) -> Option<ProcessorId> { 43e2841179SLoGin self.bmp 44e2841179SLoGin .first_false_index() 45e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 467d66c313SLoGin } 477d66c313SLoGin 487d66c313SLoGin /// 获取CpuMask中的最后一个被置位的cpu last(&self) -> Option<ProcessorId>49e2841179SLoGin pub fn last(&self) -> Option<ProcessorId> { 50e2841179SLoGin self.bmp 51e2841179SLoGin .last_index() 52e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 537d66c313SLoGin } 547d66c313SLoGin 557d66c313SLoGin /// 获取指定cpu之后第一个为1的位的cpu next_index(&self, cpu: ProcessorId) -> Option<ProcessorId>56e2841179SLoGin pub fn next_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 57e2841179SLoGin self.bmp 58e2841179SLoGin .next_index(cpu.data() as usize) 59e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 607d66c313SLoGin } 617d66c313SLoGin 627d66c313SLoGin /// 获取指定cpu之后第一个为未被置位的cpu next_zero_index(&self, cpu: ProcessorId) -> Option<ProcessorId>63e2841179SLoGin pub fn next_zero_index(&self, cpu: ProcessorId) -> Option<ProcessorId> { 64e2841179SLoGin self.bmp 65e2841179SLoGin .next_false_index(cpu.data() as usize) 66e2841179SLoGin .map(|index| ProcessorId::new(index as u32)) 67e2841179SLoGin } 68e2841179SLoGin set(&mut self, cpu: ProcessorId, value: bool) -> Option<bool>69e2841179SLoGin pub fn set(&mut self, cpu: ProcessorId, value: bool) -> Option<bool> { 70e2841179SLoGin self.bmp.set(cpu.data() as usize, value) 71e2841179SLoGin } 72e2841179SLoGin get(&self, cpu: ProcessorId) -> Option<bool>73e2841179SLoGin pub fn get(&self, cpu: ProcessorId) -> Option<bool> { 74e2841179SLoGin self.bmp.get(cpu.data() as usize) 75e2841179SLoGin } 76e2841179SLoGin is_empty(&self) -> bool77e2841179SLoGin pub fn is_empty(&self) -> bool { 78e2841179SLoGin self.bmp.is_empty() 797d66c313SLoGin } 807d66c313SLoGin 817d66c313SLoGin /// 迭代所有被置位的cpu iter_cpu(&self) -> CpuMaskIter827d66c313SLoGin pub fn iter_cpu(&self) -> CpuMaskIter { 837d66c313SLoGin CpuMaskIter { 847d66c313SLoGin mask: self, 858cb2e9b3SLoGin index: None, 867d66c313SLoGin set: true, 878cb2e9b3SLoGin begin: true, 887d66c313SLoGin } 897d66c313SLoGin } 907d66c313SLoGin 917d66c313SLoGin /// 迭代所有未被置位的cpu iter_zero_cpu(&self) -> CpuMaskIter927d66c313SLoGin pub fn iter_zero_cpu(&self) -> CpuMaskIter { 937d66c313SLoGin CpuMaskIter { 947d66c313SLoGin mask: self, 958cb2e9b3SLoGin index: None, 967d66c313SLoGin set: false, 978cb2e9b3SLoGin begin: true, 987d66c313SLoGin } 997d66c313SLoGin } 1009430523bSyuyi2439 inner(&self) -> &AllocBitmap1019430523bSyuyi2439 pub fn inner(&self) -> &AllocBitmap { 1029430523bSyuyi2439 &self.bmp 1039430523bSyuyi2439 } 104*0102d69fSLoGin bitand_assign(&mut self, rhs: &CpuMask)105*0102d69fSLoGin pub fn bitand_assign(&mut self, rhs: &CpuMask) { 106*0102d69fSLoGin self.bmp.bitand_assign(&rhs.bmp); 107*0102d69fSLoGin } 1087d66c313SLoGin } 1097d66c313SLoGin 110*0102d69fSLoGin impl BitAnd for &CpuMask { 111*0102d69fSLoGin type Output = CpuMask; 1127db6e063SLoGin bitand(self, rhs: &CpuMask) -> Self::Output113*0102d69fSLoGin fn bitand(self, rhs: &CpuMask) -> Self::Output { 114*0102d69fSLoGin let bmp = &self.bmp & &rhs.bmp; 115*0102d69fSLoGin CpuMask { bmp } 116*0102d69fSLoGin } 117*0102d69fSLoGin } 118*0102d69fSLoGin 119*0102d69fSLoGin impl Default for CpuMask { default() -> Self120*0102d69fSLoGin fn default() -> Self { 121*0102d69fSLoGin Self::new() 1227db6e063SLoGin } 1237db6e063SLoGin } 1247db6e063SLoGin 1257d66c313SLoGin pub struct CpuMaskIter<'a> { 1267d66c313SLoGin mask: &'a CpuMask, 1278cb2e9b3SLoGin index: Option<ProcessorId>, 1287d66c313SLoGin set: bool, 1298cb2e9b3SLoGin begin: bool, 1307d66c313SLoGin } 1317d66c313SLoGin 1327d66c313SLoGin impl<'a> Iterator for CpuMaskIter<'a> { 133e2841179SLoGin type Item = ProcessorId; 1347d66c313SLoGin next(&mut self) -> Option<ProcessorId>135e2841179SLoGin fn next(&mut self) -> Option<ProcessorId> { 1368cb2e9b3SLoGin if self.index.is_none() && self.begin { 1377d66c313SLoGin if self.set { 1388cb2e9b3SLoGin self.index = self.mask.first(); 1397d66c313SLoGin } else { 1408cb2e9b3SLoGin self.index = self.mask.first_zero(); 1417d66c313SLoGin } 1427d66c313SLoGin 1438cb2e9b3SLoGin self.begin = false; 1447d66c313SLoGin } 1458cb2e9b3SLoGin let result = self.index; 1468cb2e9b3SLoGin if self.set { 1478cb2e9b3SLoGin self.index = self.mask.next_index(self.index?); 1488cb2e9b3SLoGin } else { 1498cb2e9b3SLoGin self.index = self.mask.next_zero_index(self.index?); 1508cb2e9b3SLoGin } 1518cb2e9b3SLoGin 1528cb2e9b3SLoGin result 1537d66c313SLoGin } 1547d66c313SLoGin } 155e2841179SLoGin 156e2841179SLoGin impl core::fmt::Debug for CpuMask { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result157e2841179SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 158e2841179SLoGin f.debug_struct("CpuMask") 159e2841179SLoGin .field("bmp", &format!("size: {}", self.bmp.size())) 160e2841179SLoGin .finish() 161e2841179SLoGin } 162e2841179SLoGin } 163