idle.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use core::{
  2. intrinsics::unlikely,
  3. sync::atomic::{AtomicBool, Ordering},
  4. };
  5. use alloc::{sync::Arc, vec::Vec};
  6. use crate::{
  7. mm::{percpu::PerCpu, VirtAddr, IDLE_PROCESS_ADDRESS_SPACE},
  8. process::KernelStack,
  9. sched::{cpu_rq, OnRq},
  10. smp::{core::smp_get_processor_id, cpu::ProcessorId},
  11. };
  12. use super::{ProcessControlBlock, ProcessManager};
  13. static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None;
  14. impl ProcessManager {
  15. /// 初始化每个核的idle进程
  16. pub fn init_idle() {
  17. static INIT_IDLE: AtomicBool = AtomicBool::new(false);
  18. if INIT_IDLE
  19. .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
  20. .is_err()
  21. {
  22. panic!("Idle process already initialized");
  23. }
  24. assert!(
  25. smp_get_processor_id() == ProcessorId::new(0),
  26. "Idle process must be initialized on the first processor"
  27. );
  28. let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
  29. for i in 0..PerCpu::MAX_CPU_NUM {
  30. let kstack = if unlikely(i == 0) {
  31. let stack_ptr =
  32. VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
  33. // 初始化bsp的idle进程
  34. let mut ks = unsafe { KernelStack::from_existed(stack_ptr) }
  35. .expect("Failed to create kernel stack struct for BSP.");
  36. unsafe { ks.clear_pcb(true) };
  37. ks
  38. } else {
  39. KernelStack::new().unwrap_or_else(|e| {
  40. panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
  41. })
  42. };
  43. let idle_pcb = ProcessControlBlock::new_idle(i, kstack);
  44. assert!(idle_pcb.basic().user_vm().is_none());
  45. unsafe {
  46. idle_pcb
  47. .basic_mut()
  48. .set_user_vm(Some(IDLE_PROCESS_ADDRESS_SPACE()))
  49. };
  50. assert!(idle_pcb.sched_info().on_cpu().is_none());
  51. idle_pcb.sched_info().set_on_cpu(Some(ProcessorId::new(i)));
  52. *idle_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::IDLE;
  53. let rq = cpu_rq(i as usize);
  54. let (rq, _guard) = rq.self_lock();
  55. rq.set_current(Arc::downgrade(&idle_pcb));
  56. rq.set_idle(Arc::downgrade(&idle_pcb));
  57. *idle_pcb.sched_info().on_rq.lock_irqsave() = OnRq::Queued;
  58. idle_pcb
  59. .sched_info()
  60. .sched_entity()
  61. .force_mut()
  62. .set_cfs(Arc::downgrade(&rq.cfs_rq()));
  63. v.push(idle_pcb);
  64. }
  65. unsafe {
  66. __IDLE_PCB = Some(v);
  67. }
  68. }
  69. /// 获取当前的栈指针
  70. ///
  71. /// 请注意,该函数只是于辅助bsp核心的idle进程初始化
  72. fn stack_ptr() -> VirtAddr {
  73. #[cfg(target_arch = "x86_64")]
  74. return VirtAddr::new(x86::current::registers::rsp() as usize);
  75. #[cfg(target_arch = "riscv64")]
  76. {
  77. let stack_ptr: usize;
  78. unsafe {
  79. core::arch::asm!("mv {}, sp", out(reg) stack_ptr);
  80. }
  81. return VirtAddr::new(stack_ptr);
  82. }
  83. }
  84. /// 获取idle进程数组的引用
  85. pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> {
  86. unsafe { __IDLE_PCB.as_ref().unwrap() }
  87. }
  88. }