xref: /DragonOS/kernel/src/sched/syscall.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
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 let Some(next_pcb) = pcb {
25             let current_pcb = ProcessManager::current_pcb();
26             // kdebug!("sched: current_pcb: {:?}, next_pcb: {:?}\n", current_pcb, next_pcb);
27             if current_pcb.pid() != next_pcb.pid() {
28                 CPU_EXECUTING.set(smp_get_processor_id(), next_pcb.pid());
29                 unsafe { ProcessManager::switch_process(current_pcb, next_pcb) };
30             }
31         }
32         drop(irq_guard);
33         return Ok(0);
34     }
35 
36     pub fn sched_yield() -> Result<usize, SystemError> {
37         return Syscall::sched(false);
38     }
39 }
40