sched.rs 1.5 KB

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