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 let mut ks = unsafe { KernelStack::from_existed(stack_ptr) } 41 .expect("Failed to create kernel stack struct for BSP."); 42 unsafe { ks.clear_pcb(true) }; 43 ks 44 } else { 45 KernelStack::new().unwrap_or_else(|e| { 46 panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e) 47 }) 48 }; 49 50 let idle_pcb = ProcessControlBlock::new_idle(i as u32, kstack); 51 52 assert!(idle_pcb.basic().user_vm().is_none()); 53 unsafe { 54 idle_pcb 55 .basic_mut() 56 .set_user_vm(Some(INITIAL_PROCESS_ADDRESS_SPACE())) 57 }; 58 59 assert!(idle_pcb.sched_info().on_cpu().is_none()); 60 idle_pcb.sched_info().set_on_cpu(Some(i as u32)); 61 v.push(idle_pcb); 62 } 63 64 unsafe { 65 __IDLE_PCB = Some(v); 66 } 67 } 68 69 /// 获取当前的栈指针 70 /// 71 /// 请注意,该函数只是于辅助bsp核心的idle进程初始化 72 fn stack_ptr() -> VirtAddr { 73 #[cfg(target_arch = "x86_64")] 74 return VirtAddr::new(x86::current::registers::rsp() as usize); 75 76 #[cfg(target_arch = "riscv64")] 77 unimplemented!("stack_ptr() is not implemented on RISC-V") 78 } 79 80 /// 获取idle进程数组的引用 81 pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> { 82 unsafe { __IDLE_PCB.as_ref().unwrap() } 83 } 84 } 85