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