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