1 use core::{ 2 intrinsics::unlikely, 3 sync::atomic::{AtomicBool, Ordering}, 4 }; 5 6 use alloc::{sync::Arc, vec::Vec}; 7 8 use crate::{ 9 mm::{percpu::PerCpu, VirtAddr, INITIAL_PROCESS_ADDRESS_SPACE}, 10 process::KernelStack, 11 smp::core::smp_get_processor_id, 12 }; 13 14 use super::{ProcessControlBlock, ProcessManager}; 15 16 static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None; 17 18 impl ProcessManager { 19 /// 初始化每个核的idle进程 20 pub fn init_idle() { 21 static INIT_IDLE: AtomicBool = AtomicBool::new(false); 22 if INIT_IDLE 23 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 24 .is_err() 25 { 26 panic!("Idle process already initialized"); 27 } 28 29 assert!( 30 smp_get_processor_id() == 0, 31 "Idle process must be initialized on the first processor" 32 ); 33 let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM); 34 35 for i in 0..PerCpu::MAX_CPU_NUM { 36 let kstack = if unlikely(i == 0) { 37 let stack_ptr = 38 VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1))); 39 // 初始化bsp的idle进程 40 unsafe { KernelStack::from_existed(stack_ptr) } 41 .expect("Failed to create kernel stack struct for BSP.") 42 } else { 43 KernelStack::new().unwrap_or_else(|e| { 44 panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e) 45 }) 46 }; 47 48 let idle_pcb = ProcessControlBlock::new_idle(smp_get_processor_id(), kstack); 49 50 assert!(idle_pcb.basic().user_vm().is_none()); 51 unsafe { 52 idle_pcb 53 .basic_mut() 54 .set_user_vm(Some(INITIAL_PROCESS_ADDRESS_SPACE())) 55 }; 56 57 assert!(idle_pcb.sched_info().on_cpu().is_none()); 58 idle_pcb.sched_info().set_on_cpu(Some(i as u32)); 59 v.push(idle_pcb); 60 } 61 62 unsafe { 63 __IDLE_PCB = Some(v); 64 } 65 } 66 67 /// 获取当前的栈指针 68 /// 69 /// 请注意,该函数只是于辅助bsp核心的idle进程初始化 70 fn stack_ptr() -> VirtAddr { 71 #[cfg(target_arch = "x86_64")] 72 return VirtAddr::new(x86::current::registers::rsp() as usize); 73 } 74 75 /// 获取idle进程数组的引用 76 pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> { 77 unsafe { __IDLE_PCB.as_ref().unwrap() } 78 } 79 } 80