1 use core::sync::atomic::AtomicU32; 2 3 use crate::libs::cpumask::CpuMask; 4 5 mod c_adapter; 6 7 int_like!(ProcessorId, AtomicProcessorId, u32, AtomicU32); 8 9 impl ProcessorId { 10 pub const INVALID: ProcessorId = ProcessorId::new(u32::MAX); 11 } 12 13 static mut SMP_CPU_MANAGER: Option<SmpCpuManager> = None; 14 15 #[inline] 16 pub fn smp_cpu_manager() -> &'static SmpCpuManager { 17 unsafe { SMP_CPU_MANAGER.as_ref().unwrap() } 18 } 19 20 pub struct SmpCpuManager { 21 possible_cpus: CpuMask, 22 } 23 24 impl SmpCpuManager { 25 fn new() -> Self { 26 let possible_cpus = CpuMask::new(); 27 Self { possible_cpus } 28 } 29 30 /// 设置可用的CPU 31 /// 32 /// # Safety 33 /// 34 /// - 该函数不会检查CPU的有效性,调用者需要保证CPU的有效性。 35 /// - 由于possible_cpus是一个全局变量,且为了性能考虑,并不会加锁 36 /// 访问,因此该函数只能在初始化阶段调用。 37 pub unsafe fn set_possible_cpu(&self, cpu: ProcessorId, value: bool) { 38 // 强制获取mut引用,因为该函数只能在初始化阶段调用 39 let p = (self as *const Self as *mut Self).as_mut().unwrap(); 40 41 p.possible_cpus.set(cpu, value); 42 } 43 44 /// 获取可用的CPU 45 #[allow(dead_code)] 46 pub fn possible_cpus(&self) -> &CpuMask { 47 &self.possible_cpus 48 } 49 } 50 51 pub fn smp_cpu_manager_init(boot_cpu: ProcessorId) { 52 unsafe { 53 SMP_CPU_MANAGER = Some(SmpCpuManager::new()); 54 } 55 56 unsafe { smp_cpu_manager().set_possible_cpu(boot_cpu, true) }; 57 58 SmpCpuManager::arch_init(boot_cpu); 59 } 60