1 use system_error::SystemError; 2 3 use crate::{ 4 arch::CurrentIrqArch, exception::InterruptArch, process::ProcessManager, 5 smp::core::smp_get_processor_id, syscall::Syscall, 6 }; 7 8 use super::core::{do_sched, CPU_EXECUTING}; 9 10 impl Syscall { 11 /// @brief 让系统立即运行调度器的系统调用 12 /// 请注意,该系统调用不能由ring3的程序发起 13 #[inline(always)] 14 pub fn sched(from_user: bool) -> Result<usize, SystemError> { 15 let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 16 17 // 进行权限校验,拒绝用户态发起调度 18 if from_user { 19 return Err(SystemError::EPERM); 20 } 21 // 根据调度结果统一进行切换 22 let pcb = do_sched(); 23 24 if pcb.is_some() { 25 let next_pcb = pcb.unwrap(); 26 let current_pcb = ProcessManager::current_pcb(); 27 // kdebug!("sched: current_pcb: {:?}, next_pcb: {:?}\n", current_pcb, next_pcb); 28 if current_pcb.pid() != next_pcb.pid() { 29 CPU_EXECUTING.set(smp_get_processor_id(), next_pcb.pid()); 30 unsafe { ProcessManager::switch_process(current_pcb, next_pcb) }; 31 } 32 } 33 drop(irq_guard); 34 return Ok(0); 35 } 36 37 pub fn sched_yield() -> Result<usize, SystemError> { 38 return Syscall::sched(false); 39 } 40 } 41