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