xref: /DragonOS/kernel/src/arch/x86_64/sched.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
1 use core::hint::spin_loop;
2 
3 use crate::{
4     exception::InterruptArch, include::bindings::bindings::enter_syscall_int, sched::SchedArch,
5     smp::core::smp_get_processor_id, syscall::SYS_SCHED,
6 };
7 
8 use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch};
9 
10 /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
11 /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
12 #[no_mangle]
13 pub extern "C" fn sched() {
14     unsafe {
15         enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
16     }
17 }
18 
19 static mut BSP_INIT_OK: bool = false;
20 
21 pub struct X86_64SchedArch;
22 
23 impl SchedArch for X86_64SchedArch {
24     fn enable_sched_local() {
25         // fixme: 这里将来可能需要更改,毕竟这个直接开关中断有点暴力。
26         unsafe { CurrentIrqArch::interrupt_enable() };
27     }
28 
29     fn disable_sched_local() {
30         unsafe {
31             CurrentIrqArch::interrupt_disable();
32         }
33     }
34 
35     fn initial_setup_sched_local() {
36         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
37 
38         let cpu_id = smp_get_processor_id();
39 
40         if cpu_id.data() != 0 {
41             while !unsafe { BSP_INIT_OK } {
42                 spin_loop();
43             }
44         }
45 
46         apic_timer_init();
47         if smp_get_processor_id().data() == 0 {
48             unsafe {
49                 BSP_INIT_OK = true;
50             }
51         }
52 
53         drop(irq_guard);
54     }
55 }
56