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