mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
1.解决waitqueue sleep的时候,由于preempt count不为0,导致sched失败,从而导致该waitqueue下一次wakeup时,会把pcb多次加入调度队列的bug 2.修复socket inode 的read和write方法里面没有使用no_preempt的问题 3. 修复cpu0的内核栈由于脏数据导致new_idle的时候set pcb报错的问题 --------- Co-authored-by: longjin <longjin@DragonOS.org>
82 lines
2.6 KiB
Rust
82 lines
2.6 KiB
Rust
use core::{
|
||
intrinsics::unlikely,
|
||
sync::atomic::{AtomicBool, Ordering},
|
||
};
|
||
|
||
use alloc::{sync::Arc, vec::Vec};
|
||
|
||
use crate::{
|
||
mm::{percpu::PerCpu, VirtAddr, INITIAL_PROCESS_ADDRESS_SPACE},
|
||
process::KernelStack,
|
||
smp::core::smp_get_processor_id,
|
||
};
|
||
|
||
use super::{ProcessControlBlock, ProcessManager};
|
||
|
||
static mut __IDLE_PCB: Option<Vec<Arc<ProcessControlBlock>>> = None;
|
||
|
||
impl ProcessManager {
|
||
/// 初始化每个核的idle进程
|
||
pub fn init_idle() {
|
||
static INIT_IDLE: AtomicBool = AtomicBool::new(false);
|
||
if INIT_IDLE
|
||
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
|
||
.is_err()
|
||
{
|
||
panic!("Idle process already initialized");
|
||
}
|
||
|
||
assert!(
|
||
smp_get_processor_id() == 0,
|
||
"Idle process must be initialized on the first processor"
|
||
);
|
||
let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM);
|
||
|
||
for i in 0..PerCpu::MAX_CPU_NUM {
|
||
let kstack = if unlikely(i == 0) {
|
||
let stack_ptr =
|
||
VirtAddr::new(Self::stack_ptr().data() & (!(KernelStack::ALIGN - 1)));
|
||
// 初始化bsp的idle进程
|
||
let mut ks = unsafe { KernelStack::from_existed(stack_ptr) }
|
||
.expect("Failed to create kernel stack struct for BSP.");
|
||
unsafe { ks.clear_pcb(true) };
|
||
ks
|
||
} else {
|
||
KernelStack::new().unwrap_or_else(|e| {
|
||
panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e)
|
||
})
|
||
};
|
||
|
||
let idle_pcb = ProcessControlBlock::new_idle(smp_get_processor_id(), kstack);
|
||
|
||
assert!(idle_pcb.basic().user_vm().is_none());
|
||
unsafe {
|
||
idle_pcb
|
||
.basic_mut()
|
||
.set_user_vm(Some(INITIAL_PROCESS_ADDRESS_SPACE()))
|
||
};
|
||
|
||
assert!(idle_pcb.sched_info().on_cpu().is_none());
|
||
idle_pcb.sched_info().set_on_cpu(Some(i as u32));
|
||
v.push(idle_pcb);
|
||
}
|
||
|
||
unsafe {
|
||
__IDLE_PCB = Some(v);
|
||
}
|
||
}
|
||
|
||
/// 获取当前的栈指针
|
||
///
|
||
/// 请注意,该函数只是于辅助bsp核心的idle进程初始化
|
||
fn stack_ptr() -> VirtAddr {
|
||
#[cfg(target_arch = "x86_64")]
|
||
return VirtAddr::new(x86::current::registers::rsp() as usize);
|
||
}
|
||
|
||
/// 获取idle进程数组的引用
|
||
pub fn idle_pcb() -> &'static Vec<Arc<ProcessControlBlock>> {
|
||
unsafe { __IDLE_PCB.as_ref().unwrap() }
|
||
}
|
||
}
|