1 use core::sync::atomic::compiler_fence;
2 
3 use crate::{
4     arch::asm::{current::current_pcb, ptrace::user_mode},
5     include::bindings::bindings::{process_control_block, pt_regs, EPERM, SCHED_NORMAL},
6     process::process::process_cpu,
7 };
8 
9 use super::cfs::{sched_cfs_init, SchedulerCFS, __get_cfs_scheduler};
10 
11 /// @brief 获取指定的cpu上正在执行的进程的pcb
12 #[inline]
cpu_executing(cpu_id: u32) -> &'static mut process_control_block13 pub fn cpu_executing(cpu_id: u32) -> &'static mut process_control_block {
14     // todo: 引入per_cpu之后,该函数真正执行“返回指定的cpu上正在执行的pcb”的功能
15 
16     if cpu_id == process_cpu(current_pcb()) {
17         return current_pcb();
18     } else {
19         todo!()
20     }
21 }
22 
23 /// @brief 具体的调度器应当实现的trait
24 pub trait Scheduler {
25     /// @brief 使用该调度器发起调度的时候,要调用的函数
sched(&mut self)26     fn sched(&mut self);
27 
28     /// @brief 将pcb加入这个调度器的调度队列
enqueue(&mut self, pcb: &'static mut process_control_block)29     fn enqueue(&mut self, pcb: &'static mut process_control_block);
30 }
31 
__sched()32 fn __sched() {
33     compiler_fence(core::sync::atomic::Ordering::SeqCst);
34     let cfs_scheduler: &mut SchedulerCFS = __get_cfs_scheduler();
35     compiler_fence(core::sync::atomic::Ordering::SeqCst);
36 
37     cfs_scheduler.sched();
38 
39     compiler_fence(core::sync::atomic::Ordering::SeqCst);
40 }
41 
42 /// @brief 将进程加入调度队列
43 #[allow(dead_code)]
44 #[no_mangle]
sched_enqueue(pcb: &'static mut process_control_block)45 pub extern "C" fn sched_enqueue(pcb: &'static mut process_control_block) {
46     let cfs_scheduler = __get_cfs_scheduler();
47     cfs_scheduler.enqueue(pcb);
48 }
49 
50 /// @brief 初始化进程调度器模块
51 #[allow(dead_code)]
52 #[no_mangle]
sched_init()53 pub extern "C" fn sched_init() {
54     unsafe {
55         sched_cfs_init();
56     }
57 }
58 
59 /// @brief 当时钟中断到达时,更新时间片
60 /// 请注意,该函数只能被时钟中断处理程序调用
61 #[allow(dead_code)]
62 #[no_mangle]
sched_update_jiffies()63 pub extern "C" fn sched_update_jiffies() {
64     match current_pcb().policy {
65         SCHED_NORMAL => {
66             __get_cfs_scheduler().timer_update_jiffies();
67         }
68         _ => {
69             todo!()
70         }
71     }
72 }
73 
74 /// @brief 让系统立即运行调度器的系统调用
75 /// 请注意,该系统调用不能由ring3的程序发起
76 #[allow(dead_code)]
77 #[no_mangle]
sys_sched(regs: &'static mut pt_regs) -> u6478 pub extern "C" fn sys_sched(regs: &'static mut pt_regs) -> u64 {
79     // 进行权限校验,拒绝用户态发起调度
80     if user_mode(regs) {
81         return (-(EPERM as i64)) as u64;
82     }
83     __sched();
84     0
85 }
86