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)]
sched(from_user: bool) -> Result<usize, SystemError>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 
sched_yield() -> Result<usize, SystemError>37     pub fn sched_yield() -> Result<usize, SystemError> {
38         return Syscall::sched(false);
39     }
40 }
41