xref: /DragonOS/kernel/src/libs/cpumask.rs (revision 0102d69fdd231e472d7bb3d609a41ae56a3799ee)
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