Quellcode durchsuchen

feat(sched): add sched_yield (#766)

* 实现sched_yield系统调用
zwb0x00 vor 10 Monaten
Ursprung
Commit
173c4567cf
3 geänderte Dateien mit 40 neuen und 0 gelöschten Zeilen
  1. 1 0
      kernel/src/sched/mod.rs
  2. 37 0
      kernel/src/sched/syscall.rs
  3. 2 0
      kernel/src/syscall/mod.rs

+ 1 - 0
kernel/src/sched/mod.rs

@@ -5,6 +5,7 @@ pub mod fair;
 pub mod idle;
 pub mod pelt;
 pub mod prio;
+pub mod syscall;
 
 use core::{
     intrinsics::{likely, unlikely},

+ 37 - 0
kernel/src/sched/syscall.rs

@@ -0,0 +1,37 @@
+use system_error::SystemError;
+
+use crate::arch::cpu::current_cpu_id;
+use crate::exception::InterruptArch;
+use crate::process::ProcessManager;
+use crate::sched::CurrentIrqArch;
+use crate::sched::Scheduler;
+use crate::syscall::Syscall;
+
+use super::fair::CompletelyFairScheduler;
+use super::{cpu_rq, schedule, SchedMode};
+
+impl Syscall {
+    pub fn do_sched_yield() -> Result<usize, SystemError> {
+        // 禁用中断
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+
+        let pcb = ProcessManager::current_pcb();
+        let rq = cpu_rq(pcb.sched_info().on_cpu().unwrap_or(current_cpu_id()).data() as usize);
+        let (rq, guard) = rq.self_lock();
+
+        // TODO: schedstat_inc(rq->yld_count);
+
+        CompletelyFairScheduler::yield_task(rq);
+
+        pcb.preempt_disable();
+
+        drop(guard);
+        drop(irq_guard);
+
+        pcb.preempt_enable(); // sched_preempt_enable_no_resched();
+
+        schedule(SchedMode::SM_NONE);
+
+        Ok(0)
+    }
+}

+ 2 - 0
kernel/src/syscall/mod.rs

@@ -1007,6 +1007,8 @@ impl Syscall {
                 Self::fchmodat(dirfd, pathname, mode)
             }
 
+            SYS_SCHED_YIELD => Self::do_sched_yield(),
+
             SYS_SCHED_GETAFFINITY => {
                 let pid = args[0] as i32;
                 let size = args[1];