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, IDLE_PROCESS_ADDRESS_SPACE}, 10 process::KernelStack, 11 sched::{cpu_rq, OnRq}, 12 smp::{core::smp_get_processor_id, cpu::ProcessorId}, 13 }; 14 15 use super::{ProcessControlBlock, ProcessManager}; 16 17 static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None; 18 19 impl ProcessManager { 20 /// 初始化每个核的idle进程 21 pub fn init_idle() { 22 static INIT_IDLE: AtomicBool = AtomicBool::new(false); 23 if INIT_IDLE 24 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 25 .is_err() 26 { 27 panic!("Idle process already initialized"); 28 } 29 30 assert!( 31 smp_get_processor_id() == ProcessorId::new(0), 32 "Idle process must be initialized on the first processor" 33 ); 34 let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize); 35 36 for i in 0..PerCpu::MAX_CPU_NUM { 37 let kstack = if unlikely(i == 0) { 38 let stack_ptr = 39 VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1))); 40 // 初始化bsp的idle进程 41 let mut ks = unsafe { KernelStack::from_existed(stack_ptr) } 42 .expect("Failed to create kernel stack struct for BSP."); 43 unsafe { ks.clear_pcb(true) }; 44 ks 45 } else { 46 KernelStack::new().unwrap_or_else(|e| { 47 panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e) 48 }) 49 }; 50 51 let idle_pcb = ProcessControlBlock::new_idle(i, kstack); 52 53 assert!(idle_pcb.basic().user_vm().is_none()); 54 unsafe { 55 idle_pcb 56 .basic_mut() 57 .set_user_vm(Some(IDLE_PROCESS_ADDRESS_SPACE())) 58 }; 59 60 assert!(idle_pcb.sched_info().on_cpu().is_none()); 61 idle_pcb.sched_info().set_on_cpu(Some(ProcessorId::new(i))); 62 *idle_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::IDLE; 63 64 let rq = cpu_rq(i as usize); 65 let (rq, _guard) = rq.self_lock(); 66 rq.set_current(Arc::downgrade(&idle_pcb)); 67 rq.set_idle(Arc::downgrade(&idle_pcb)); 68 69 *idle_pcb.sched_info().on_rq.lock_irqsave() = OnRq::Queued; 70 71 idle_pcb 72 .sched_info() 73 .sched_entity() 74 .force_mut() 75 .set_cfs(Arc::downgrade(&rq.cfs_rq())); 76 77 v.push(idle_pcb); 78 } 79 80 unsafe { 81 __IDLE_PCB = Some(v); 82 } 83 } 84 85 /// 获取当前的栈指针 86 /// 87 /// 请注意,该函数只是于辅助bsp核心的idle进程初始化 88 fn stack_ptr() -> VirtAddr { 89 #[cfg(target_arch = "x86_64")] 90 return VirtAddr::new(x86::current::registers::rsp() as usize); 91 92 #[cfg(target_arch = "riscv64")] 93 { 94 let stack_ptr: usize; 95 unsafe { 96 core::arch::asm!("mv {}, sp", out(reg) stack_ptr); 97 } 98 return VirtAddr::new(stack_ptr); 99 } 100 } 101 102 /// 获取idle进程数组的引用 103 pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> { 104 unsafe { __IDLE_PCB.as_ref().unwrap() } 105 } 106 } 107