mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-11 04:56:48 +00:00
Patch fix sched and net lockdep error (#479)
- fix: 修复调度器,软中断,定时器,网络子系统的部分锁的使用不符合锁依赖安全规范的问题 - fix: 修复创建pcb时内核栈爆栈的问题 - 把异常的trap gate改成intr gate --------- Co-authored-by: GnoCiYeH <heyicong@dragonos.org>
This commit is contained in:
parent
91e9d4ab55
commit
0d6cf65aa1
@ -57,9 +57,10 @@ int apic_init()
|
|||||||
*/
|
*/
|
||||||
void do_IRQ(struct pt_regs *rsp, ul number)
|
void do_IRQ(struct pt_regs *rsp, ul number)
|
||||||
{
|
{
|
||||||
if((rsp->cs & 0x3) == 3)
|
|
||||||
|
if ((rsp->cs & 0x3) == 3)
|
||||||
{
|
{
|
||||||
asm volatile("swapgs":::"memory");
|
asm volatile("swapgs" ::: "memory");
|
||||||
}
|
}
|
||||||
if (number < 0x80 && number >= 32) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
if (number < 0x80 && number >= 32) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ pub enum LocalApicTimerMode {
|
|||||||
impl LocalApicTimer {
|
impl LocalApicTimer {
|
||||||
/// 定时器中断的间隔
|
/// 定时器中断的间隔
|
||||||
pub const INTERVAL_MS: u64 = 1000 / HZ as u64;
|
pub const INTERVAL_MS: u64 = 1000 / HZ as u64;
|
||||||
pub const DIVISOR: u64 = 3;
|
pub const DIVISOR: u64 = 4;
|
||||||
|
|
||||||
/// IoApicManager 初值为0或false
|
/// IoApicManager 初值为0或false
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
@ -131,7 +131,7 @@ impl LocalApicTimer {
|
|||||||
// 疑惑:这里使用khz吗?
|
// 疑惑:这里使用khz吗?
|
||||||
// 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的
|
// 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的
|
||||||
// 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑
|
// 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑
|
||||||
let count = cpu_khz * Self::INTERVAL_MS / (1000 * Self::DIVISOR);
|
let count = cpu_khz * Self::INTERVAL_MS / (Self::DIVISOR);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,15 @@ use acpi::HpetInfo;
|
|||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
arch::CurrentIrqArch,
|
||||||
driver::{
|
driver::{
|
||||||
acpi::acpi_manager,
|
acpi::acpi_manager,
|
||||||
timers::hpet::{HpetRegisters, HpetTimerRegisters},
|
timers::hpet::{HpetRegisters, HpetTimerRegisters},
|
||||||
},
|
},
|
||||||
exception::softirq::{softirq_vectors, SoftirqNumber},
|
exception::{
|
||||||
|
softirq::{softirq_vectors, SoftirqNumber},
|
||||||
|
InterruptArch,
|
||||||
|
},
|
||||||
kdebug, kerror, kinfo,
|
kdebug, kerror, kinfo,
|
||||||
libs::{
|
libs::{
|
||||||
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||||
@ -51,8 +55,8 @@ struct InnerHpet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Hpet {
|
impl Hpet {
|
||||||
/// HPET0 中断间隔为500us
|
/// HPET0 中断间隔为 10ms
|
||||||
pub const HPET0_INTERVAL_USEC: u64 = 500;
|
pub const HPET0_INTERVAL_USEC: u64 = 10000;
|
||||||
|
|
||||||
fn new(mut hpet_info: HpetInfo) -> Result<Self, SystemError> {
|
fn new(mut hpet_info: HpetInfo) -> Result<Self, SystemError> {
|
||||||
let paddr = PhysAddr::new(hpet_info.base_address);
|
let paddr = PhysAddr::new(hpet_info.base_address);
|
||||||
@ -222,7 +226,8 @@ impl Hpet {
|
|||||||
/// 处理HPET的中断
|
/// 处理HPET的中断
|
||||||
pub(super) fn handle_irq(&self, timer_num: u32) {
|
pub(super) fn handle_irq(&self, timer_num: u32) {
|
||||||
if timer_num == 0 {
|
if timer_num == 0 {
|
||||||
update_timer_jiffies(Self::HPET0_INTERVAL_USEC);
|
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||||
|
update_timer_jiffies(Self::HPET0_INTERVAL_USEC, Self::HPET0_INTERVAL_USEC as i64);
|
||||||
|
|
||||||
if let Ok(first_expire) = timer_get_first_expire() {
|
if let Ok(first_expire) = timer_get_first_expire() {
|
||||||
if first_expire <= clock() {
|
if first_expire <= clock() {
|
||||||
|
@ -239,6 +239,17 @@ impl TSCManager {
|
|||||||
///
|
///
|
||||||
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/arch/x86/kernel/tsc.c#389
|
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/arch/x86/kernel/tsc.c#389
|
||||||
fn pit_calibrate_tsc(latch: u64, ms: u64, loopmin: u64) -> Option<u64> {
|
fn pit_calibrate_tsc(latch: u64, ms: u64, loopmin: u64) -> Option<u64> {
|
||||||
|
// 当前暂时没写legacy pic的驱动,因此这里直接返回
|
||||||
|
let has_legacy_pic = false;
|
||||||
|
if !has_legacy_pic {
|
||||||
|
let mut cnt = 10000;
|
||||||
|
while cnt > 0 {
|
||||||
|
cnt -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Set the Gate high, disable speaker
|
// Set the Gate high, disable speaker
|
||||||
let d = (CurrentPortIOArch::in8(0x61) & (!0x02)) | 0x01;
|
let d = (CurrentPortIOArch::in8(0x61) & (!0x02)) | 0x01;
|
||||||
|
@ -384,7 +384,7 @@ impl SigContext {
|
|||||||
/// - `false` -> 执行失败
|
/// - `false` -> 执行失败
|
||||||
pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
|
pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
|
||||||
let guard = ProcessManager::current_pcb();
|
let guard = ProcessManager::current_pcb();
|
||||||
let mut arch_info = guard.arch_info();
|
let mut arch_info = guard.arch_info_irqsave();
|
||||||
(*frame) = self.frame.clone();
|
(*frame) = self.frame.clone();
|
||||||
// (*current_thread).trap_num = (*context).trap_num;
|
// (*current_thread).trap_num = (*context).trap_num;
|
||||||
*arch_info.cr2_mut() = self.cr2 as usize;
|
*arch_info.cr2_mut() = self.cr2 as usize;
|
||||||
|
@ -98,6 +98,7 @@ impl ArchPCBInfo {
|
|||||||
/// ## 返回值
|
/// ## 返回值
|
||||||
///
|
///
|
||||||
/// 返回一个新的ArchPCBInfo
|
/// 返回一个新的ArchPCBInfo
|
||||||
|
#[inline(never)]
|
||||||
pub fn new(kstack: &KernelStack) -> Self {
|
pub fn new(kstack: &KernelStack) -> Self {
|
||||||
let mut r = Self {
|
let mut r = Self {
|
||||||
rflags: 0,
|
rflags: 0,
|
||||||
@ -325,7 +326,7 @@ impl ProcessManager {
|
|||||||
child_trapframe.set_return_value(0);
|
child_trapframe.set_return_value(0);
|
||||||
|
|
||||||
// 设置子进程的栈基址(开始执行中断返回流程时的栈基址)
|
// 设置子进程的栈基址(开始执行中断返回流程时的栈基址)
|
||||||
let mut new_arch_guard = new_pcb.arch_info();
|
let mut new_arch_guard = unsafe { new_pcb.arch_info() };
|
||||||
let kernel_stack_guard = new_pcb.kernel_stack();
|
let kernel_stack_guard = new_pcb.kernel_stack();
|
||||||
|
|
||||||
// 设置子进程在内核态开始执行时的rsp、rbp
|
// 设置子进程在内核态开始执行时的rsp、rbp
|
||||||
@ -385,13 +386,13 @@ impl ProcessManager {
|
|||||||
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||||
|
|
||||||
// 保存浮点寄存器
|
// 保存浮点寄存器
|
||||||
prev.arch_info().save_fp_state();
|
prev.arch_info_irqsave().save_fp_state();
|
||||||
// 切换浮点寄存器
|
// 切换浮点寄存器
|
||||||
next.arch_info().restore_fp_state();
|
next.arch_info_irqsave().restore_fp_state();
|
||||||
|
|
||||||
// 切换fsbase
|
// 切换fsbase
|
||||||
prev.arch_info().save_fsbase();
|
prev.arch_info_irqsave().save_fsbase();
|
||||||
next.arch_info().restore_fsbase();
|
next.arch_info_irqsave().restore_fsbase();
|
||||||
|
|
||||||
// 切换gsbase
|
// 切换gsbase
|
||||||
Self::switch_gsbase(&prev, &next);
|
Self::switch_gsbase(&prev, &next);
|
||||||
@ -406,8 +407,8 @@ impl ProcessManager {
|
|||||||
// 切换内核栈
|
// 切换内核栈
|
||||||
|
|
||||||
// 获取arch info的锁,并强制泄露其守卫(切换上下文后,在switch_finish_hook中会释放锁)
|
// 获取arch info的锁,并强制泄露其守卫(切换上下文后,在switch_finish_hook中会释放锁)
|
||||||
let next_arch = SpinLockGuard::leak(next.arch_info()) as *mut ArchPCBInfo;
|
let next_arch = SpinLockGuard::leak(next.arch_info_irqsave()) as *mut ArchPCBInfo;
|
||||||
let prev_arch = SpinLockGuard::leak(prev.arch_info()) as *mut ArchPCBInfo;
|
let prev_arch = SpinLockGuard::leak(prev.arch_info_irqsave()) as *mut ArchPCBInfo;
|
||||||
|
|
||||||
(*prev_arch).rip = switch_back as usize;
|
(*prev_arch).rip = switch_back as usize;
|
||||||
|
|
||||||
@ -430,10 +431,10 @@ impl ProcessManager {
|
|||||||
|
|
||||||
unsafe fn switch_gsbase(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) {
|
unsafe fn switch_gsbase(prev: &Arc<ProcessControlBlock>, next: &Arc<ProcessControlBlock>) {
|
||||||
asm!("swapgs", options(nostack, preserves_flags));
|
asm!("swapgs", options(nostack, preserves_flags));
|
||||||
prev.arch_info().save_gsbase();
|
prev.arch_info_irqsave().save_gsbase();
|
||||||
next.arch_info().restore_gsbase();
|
next.arch_info_irqsave().restore_gsbase();
|
||||||
// 将下一个进程的kstack写入kernel_gsbase
|
// 将下一个进程的kstack写入kernel_gsbase
|
||||||
next.arch_info().store_kernel_gsbase();
|
next.arch_info_irqsave().store_kernel_gsbase();
|
||||||
asm!("swapgs", options(nostack, preserves_flags));
|
asm!("swapgs", options(nostack, preserves_flags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,11 @@ macro_rules! syscall_return {
|
|||||||
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||||
let syscall_num = frame.rax as usize;
|
let syscall_num = frame.rax as usize;
|
||||||
// 防止sys_sched由于超时无法退出导致的死锁
|
// 防止sys_sched由于超时无法退出导致的死锁
|
||||||
if syscall_num != SYS_SCHED {
|
if syscall_num == SYS_SCHED {
|
||||||
|
unsafe {
|
||||||
|
CurrentIrqArch::interrupt_disable();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
CurrentIrqArch::interrupt_enable();
|
CurrentIrqArch::interrupt_enable();
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,8 @@ pub fn e1000e_driver_init(device: E1000EDevice) {
|
|||||||
let driver = E1000EDriver::new(device);
|
let driver = E1000EDriver::new(device);
|
||||||
let iface = E1000EInterface::new(driver);
|
let iface = E1000EInterface::new(driver);
|
||||||
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
||||||
NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
|
NET_DRIVERS
|
||||||
|
.write_irqsave()
|
||||||
|
.insert(iface.nic_id(), iface.clone());
|
||||||
kinfo!("e1000e driver init successfully!\tMAC: [{}]", mac);
|
kinfo!("e1000e driver init successfully!\tMAC: [{}]", mac);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,9 @@ pub fn virtio_net<T: Transport + 'static>(transport: T) {
|
|||||||
let iface = VirtioInterface::new(driver);
|
let iface = VirtioInterface::new(driver);
|
||||||
let name = iface.name.clone();
|
let name = iface.name.clone();
|
||||||
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
||||||
NET_DRIVERS.write().insert(iface.nic_id(), iface.clone());
|
NET_DRIVERS
|
||||||
|
.write_irqsave()
|
||||||
|
.insert(iface.nic_id(), iface.clone());
|
||||||
kinfo!(
|
kinfo!(
|
||||||
"Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
|
"Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
|
||||||
name,
|
name,
|
||||||
|
@ -3,16 +3,21 @@ use core::{
|
|||||||
intrinsics::unlikely,
|
intrinsics::unlikely,
|
||||||
mem::{self, MaybeUninit},
|
mem::{self, MaybeUninit},
|
||||||
ptr::null_mut,
|
ptr::null_mut,
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, AtomicI16, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::CurrentIrqArch, exception::InterruptArch, kdebug, kinfo, libs::rwlock::RwLock,
|
arch::CurrentIrqArch,
|
||||||
mm::percpu::PerCpu, process::ProcessManager, smp::core::smp_get_processor_id,
|
exception::InterruptArch,
|
||||||
|
kdebug, kinfo,
|
||||||
|
libs::rwlock::RwLock,
|
||||||
|
mm::percpu::{PerCpu, PerCpuVar},
|
||||||
|
process::ProcessManager,
|
||||||
|
smp::core::smp_get_processor_id,
|
||||||
time::timer::clock,
|
time::timer::clock,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,8 +99,12 @@ pub trait SoftirqVec: Send + Sync + Debug {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Softirq {
|
pub struct Softirq {
|
||||||
table: RwLock<[Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>,
|
table: RwLock<[Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>,
|
||||||
|
/// 软中断嵌套层数(per cpu)
|
||||||
|
cpu_running_count: PerCpuVar<AtomicI16>,
|
||||||
}
|
}
|
||||||
impl Softirq {
|
impl Softirq {
|
||||||
|
/// 每个CPU最大嵌套的软中断数量
|
||||||
|
const MAX_RUNNING_PER_CPU: i16 = 3;
|
||||||
fn new() -> Softirq {
|
fn new() -> Softirq {
|
||||||
let mut data: [MaybeUninit<Option<Arc<dyn SoftirqVec>>>; MAX_SOFTIRQ_NUM as usize] =
|
let mut data: [MaybeUninit<Option<Arc<dyn SoftirqVec>>>; MAX_SOFTIRQ_NUM as usize] =
|
||||||
unsafe { MaybeUninit::uninit().assume_init() };
|
unsafe { MaybeUninit::uninit().assume_init() };
|
||||||
@ -108,11 +117,20 @@ impl Softirq {
|
|||||||
mem::transmute::<_, [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>(data)
|
mem::transmute::<_, [Option<Arc<dyn SoftirqVec>>; MAX_SOFTIRQ_NUM as usize]>(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut percpu_count = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
|
||||||
|
percpu_count.resize_with(PerCpu::MAX_CPU_NUM as usize, || AtomicI16::new(0));
|
||||||
|
let cpu_running_count = PerCpuVar::new(percpu_count).unwrap();
|
||||||
|
|
||||||
return Softirq {
|
return Softirq {
|
||||||
table: RwLock::new(data),
|
table: RwLock::new(data),
|
||||||
|
cpu_running_count,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cpu_running_count(&self) -> &PerCpuVar<AtomicI16> {
|
||||||
|
return &self.cpu_running_count;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief 注册软中断向量
|
/// @brief 注册软中断向量
|
||||||
///
|
///
|
||||||
/// @param softirq_num 中断向量号
|
/// @param softirq_num 中断向量号
|
||||||
@ -127,7 +145,7 @@ impl Softirq {
|
|||||||
|
|
||||||
// let self = &mut SOFTIRQ_VECTORS.lock();
|
// let self = &mut SOFTIRQ_VECTORS.lock();
|
||||||
// 判断该软中断向量是否已经被注册
|
// 判断该软中断向量是否已经被注册
|
||||||
let mut table_guard = self.table.write();
|
let mut table_guard = self.table.write_irqsave();
|
||||||
if table_guard[softirq_num as usize].is_some() {
|
if table_guard[softirq_num as usize].is_some() {
|
||||||
// kdebug!("register_softirq failed");
|
// kdebug!("register_softirq failed");
|
||||||
|
|
||||||
@ -149,7 +167,7 @@ impl Softirq {
|
|||||||
/// @param irq_num 中断向量号码
|
/// @param irq_num 中断向量号码
|
||||||
pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
|
pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
|
||||||
// kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
|
// kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
|
||||||
let mut table_guard = self.table.write();
|
let mut table_guard = self.table.write_irqsave();
|
||||||
// 将软中断向量清空
|
// 将软中断向量清空
|
||||||
table_guard[softirq_num as usize] = None;
|
table_guard[softirq_num as usize] = None;
|
||||||
drop(table_guard);
|
drop(table_guard);
|
||||||
@ -162,8 +180,14 @@ impl Softirq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_softirq(&self) {
|
pub fn do_softirq(&self) {
|
||||||
|
if self.cpu_running_count().get().load(Ordering::SeqCst) >= Self::MAX_RUNNING_PER_CPU {
|
||||||
|
// 当前CPU的软中断嵌套层数已经达到最大值,不再执行
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 创建一个RunningCountGuard,当退出作用域时,会自动将cpu_running_count减1
|
||||||
|
let _count_guard = RunningCountGuard::new(self.cpu_running_count());
|
||||||
|
|
||||||
// TODO pcb的flags未修改
|
// TODO pcb的flags未修改
|
||||||
// todo: 是否需要判断在当前cpu上面,该函数的嵌套层数?(防止爆栈)
|
|
||||||
let end = clock() + 500 * 2;
|
let end = clock() + 500 * 2;
|
||||||
let cpu_id = smp_get_processor_id();
|
let cpu_id = smp_get_processor_id();
|
||||||
let mut max_restart = MAX_SOFTIRQ_RESTART;
|
let mut max_restart = MAX_SOFTIRQ_RESTART;
|
||||||
@ -180,7 +204,7 @@ impl Softirq {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let table_guard = self.table.read();
|
let table_guard = self.table.read_irqsave();
|
||||||
let softirq_func = table_guard[i as usize].clone();
|
let softirq_func = table_guard[i as usize].clone();
|
||||||
drop(table_guard);
|
drop(table_guard);
|
||||||
if softirq_func.is_none() {
|
if softirq_func.is_none() {
|
||||||
@ -236,6 +260,27 @@ impl Softirq {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 当前CPU的软中断嵌套层数的计数器守卫
|
||||||
|
///
|
||||||
|
/// 当进入作用域时,会自动将cpu_running_count加1,
|
||||||
|
/// 当退出作用域时,会自动将cpu_running_count减1
|
||||||
|
struct RunningCountGuard<'a> {
|
||||||
|
cpu_running_count: &'a PerCpuVar<AtomicI16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RunningCountGuard<'a> {
|
||||||
|
fn new(cpu_running_count: &'a PerCpuVar<AtomicI16>) -> RunningCountGuard {
|
||||||
|
cpu_running_count.get().fetch_add(1, Ordering::SeqCst);
|
||||||
|
return RunningCountGuard { cpu_running_count };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for RunningCountGuard<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.cpu_running_count.get().fetch_sub(1, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ======= 以下为给C提供的接口 =======
|
// ======= 以下为给C提供的接口 =======
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rs_raise_softirq(softirq_num: u32) {
|
pub extern "C" fn rs_raise_softirq(softirq_num: u32) {
|
||||||
|
@ -316,27 +316,27 @@ void sys_vector_init()
|
|||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
set_intr_gate(i, 0, ignore_int);
|
set_intr_gate(i, 0, ignore_int);
|
||||||
|
|
||||||
set_trap_gate(0, 0, divide_error);
|
set_intr_gate(0, 0, divide_error);
|
||||||
set_trap_gate(1, 0, debug);
|
set_intr_gate(1, 0, debug);
|
||||||
set_intr_gate(2, 0, nmi);
|
set_intr_gate(2, 0, nmi);
|
||||||
set_system_trap_gate(3, 0, int3);
|
set_system_trap_gate(3, 0, int3);
|
||||||
set_system_trap_gate(4, 0, overflow);
|
set_system_trap_gate(4, 0, overflow);
|
||||||
set_system_trap_gate(5, 0, bounds);
|
set_system_trap_gate(5, 0, bounds);
|
||||||
set_trap_gate(6, 0, undefined_opcode);
|
set_intr_gate(6, 0, undefined_opcode);
|
||||||
set_trap_gate(7, 0, dev_not_avaliable);
|
set_intr_gate(7, 0, dev_not_avaliable);
|
||||||
set_trap_gate(8, 0, double_fault);
|
set_intr_gate(8, 0, double_fault);
|
||||||
set_trap_gate(9, 0, coprocessor_segment_overrun);
|
set_intr_gate(9, 0, coprocessor_segment_overrun);
|
||||||
set_trap_gate(10, 0, invalid_TSS);
|
set_intr_gate(10, 0, invalid_TSS);
|
||||||
set_trap_gate(11, 0, segment_not_exists);
|
set_intr_gate(11, 0, segment_not_exists);
|
||||||
set_trap_gate(12, 0, stack_segment_fault);
|
set_intr_gate(12, 0, stack_segment_fault);
|
||||||
set_trap_gate(13, 0, general_protection);
|
set_intr_gate(13, 0, general_protection);
|
||||||
set_trap_gate(14, 0, page_fault);
|
set_intr_gate(14, 0, page_fault);
|
||||||
// 中断号15由Intel保留,不能使用
|
// 中断号15由Intel保留,不能使用
|
||||||
set_trap_gate(16, 0, x87_FPU_error);
|
set_intr_gate(16, 0, x87_FPU_error);
|
||||||
set_trap_gate(17, 0, alignment_check);
|
set_intr_gate(17, 0, alignment_check);
|
||||||
set_trap_gate(18, 0, machine_check);
|
set_intr_gate(18, 0, machine_check);
|
||||||
set_trap_gate(19, 0, SIMD_exception);
|
set_intr_gate(19, 0, SIMD_exception);
|
||||||
set_trap_gate(20, 0, virtualization_exception);
|
set_intr_gate(20, 0, virtualization_exception);
|
||||||
// 中断号21-31由Intel保留,不能使用
|
// 中断号21-31由Intel保留,不能使用
|
||||||
|
|
||||||
// 32-255为用户自定义中断内部
|
// 32-255为用户自定义中断内部
|
||||||
|
@ -146,7 +146,7 @@ impl ProcFSInode {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let sched_info_guard = pcb.sched_info();
|
let sched_info_guard = pcb.sched_info();
|
||||||
let state = sched_info_guard.state();
|
let state = sched_info_guard.inner_lock_read_irqsave().state();
|
||||||
let cpu_id = sched_info_guard
|
let cpu_id = sched_info_guard
|
||||||
.on_cpu()
|
.on_cpu()
|
||||||
.map(|cpu| cpu as i32)
|
.map(|cpu| cpu as i32)
|
||||||
@ -155,8 +155,6 @@ impl ProcFSInode {
|
|||||||
let priority = sched_info_guard.priority();
|
let priority = sched_info_guard.priority();
|
||||||
let vrtime = sched_info_guard.virtual_runtime();
|
let vrtime = sched_info_guard.virtual_runtime();
|
||||||
|
|
||||||
drop(sched_info_guard);
|
|
||||||
|
|
||||||
pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
|
pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
|
||||||
pdata.append(
|
pdata.append(
|
||||||
&mut format!("\nPid:\t{}", pcb.pid().into())
|
&mut format!("\nPid:\t{}", pcb.pid().into())
|
||||||
|
@ -201,10 +201,8 @@ impl Signal {
|
|||||||
if *self == Signal::SIGKILL {
|
if *self == Signal::SIGKILL {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
let state = pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
if pcb.sched_info().state().is_blocked()
|
if state.is_blocked() && (state.is_blocked_interruptable() == false) {
|
||||||
&& (pcb.sched_info().state().is_blocked_interruptable() == false)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +285,7 @@ fn signal_wake_up(pcb: Arc<ProcessControlBlock>, _guard: SpinLockGuard<SignalStr
|
|||||||
// 如果不是 fatal 的就只唤醒 stop 的进程来响应
|
// 如果不是 fatal 的就只唤醒 stop 的进程来响应
|
||||||
// kdebug!("signal_wake_up");
|
// kdebug!("signal_wake_up");
|
||||||
// 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
|
// 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
|
||||||
let state = pcb.sched_info().state();
|
let state = pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
let mut wakeup_ok = true;
|
let mut wakeup_ok = true;
|
||||||
if state.is_blocked_interruptable() {
|
if state.is_blocked_interruptable() {
|
||||||
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
|
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
|
||||||
@ -337,7 +335,7 @@ fn recalc_sigpending() {
|
|||||||
pub fn flush_signal_handlers(pcb: Arc<ProcessControlBlock>, force_default: bool) {
|
pub fn flush_signal_handlers(pcb: Arc<ProcessControlBlock>, force_default: bool) {
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
// kdebug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
|
// kdebug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
|
||||||
let actions = &mut pcb.sig_struct().handlers;
|
let actions = &mut pcb.sig_struct_irqsave().handlers;
|
||||||
|
|
||||||
for sigaction in actions.iter_mut() {
|
for sigaction in actions.iter_mut() {
|
||||||
if force_default || !sigaction.is_ignore() {
|
if force_default || !sigaction.is_ignore() {
|
||||||
@ -436,7 +434,7 @@ pub fn set_current_sig_blocked(new_set: &mut SigSet) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let guard = pcb.sig_struct_irq();
|
let guard = pcb.sig_struct_irqsave();
|
||||||
// todo: 当一个进程有多个线程后,在这里需要设置每个线程的block字段,并且 retarget_shared_pending(虽然我还没搞明白linux这部分是干啥的)
|
// todo: 当一个进程有多个线程后,在这里需要设置每个线程的block字段,并且 retarget_shared_pending(虽然我还没搞明白linux这部分是干啥的)
|
||||||
|
|
||||||
// 设置当前进程的sig blocked
|
// 设置当前进程的sig blocked
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
use core::{ffi::c_void, mem::size_of, sync::atomic::AtomicI64};
|
use core::{
|
||||||
|
ffi::c_void,
|
||||||
|
mem::size_of,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
sync::atomic::AtomicI64,
|
||||||
|
};
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -55,13 +60,41 @@ pub const SIG_KERNEL_IGNORE_MASK: SigSet = Signal::into_sigset(Signal::SIGCONT)
|
|||||||
/// SignalStruct 在 pcb 中加锁
|
/// SignalStruct 在 pcb 中加锁
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SignalStruct {
|
pub struct SignalStruct {
|
||||||
|
inner: Box<InnerSignalStruct>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InnerSignalStruct {
|
||||||
pub cnt: AtomicI64,
|
pub cnt: AtomicI64,
|
||||||
/// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此
|
/// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此
|
||||||
/// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋
|
/// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋
|
||||||
pub handlers: [Sigaction; MAX_SIG_NUM as usize],
|
pub handlers: [Sigaction; MAX_SIG_NUM as usize],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SignalStruct {
|
impl SignalStruct {
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Box::new(InnerSignalStruct::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for SignalStruct {
|
||||||
|
type Target = InnerSignalStruct;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for SignalStruct {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InnerSignalStruct {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
cnt: Default::default(),
|
cnt: Default::default(),
|
||||||
|
@ -164,6 +164,7 @@ impl<T> RwLock<T> {
|
|||||||
} //忙等待
|
} //忙等待
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 关中断并获取读者守卫
|
||||||
pub fn read_irqsave(&self) -> RwLockReadGuard<T> {
|
pub fn read_irqsave(&self) -> RwLockReadGuard<T> {
|
||||||
loop {
|
loop {
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
@ -177,6 +178,17 @@ impl<T> RwLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 尝试关闭中断并获取读者守卫
|
||||||
|
pub fn try_read_irqsave(&self) -> Option<RwLockReadGuard<T>> {
|
||||||
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
|
if let Some(mut guard) = self.try_read() {
|
||||||
|
guard.irq_guard = Some(irq_guard);
|
||||||
|
return Some(guard);
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
/// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值
|
/// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值
|
||||||
|
@ -184,18 +184,27 @@ impl WaitQueue {
|
|||||||
/// @return true 成功唤醒进程
|
/// @return true 成功唤醒进程
|
||||||
/// @return false 没有唤醒进程
|
/// @return false 没有唤醒进程
|
||||||
pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
|
pub fn wakeup(&self, state: Option<ProcessState>) -> bool {
|
||||||
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
|
let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock_irqsave();
|
||||||
// 如果队列为空,则返回
|
// 如果队列为空,则返回
|
||||||
if guard.wait_list.is_empty() {
|
if guard.wait_list.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
|
// 如果队列头部的pcb的state与给定的state相与,结果不为0,则唤醒
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
if guard.wait_list.front().unwrap().sched_info().state() != state {
|
if guard
|
||||||
|
.wait_list
|
||||||
|
.front()
|
||||||
|
.unwrap()
|
||||||
|
.sched_info()
|
||||||
|
.inner_lock_read_irqsave()
|
||||||
|
.state()
|
||||||
|
!= state
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let to_wakeup = guard.wait_list.pop_front().unwrap();
|
let to_wakeup = guard.wait_list.pop_front().unwrap();
|
||||||
|
drop(guard);
|
||||||
let res = ProcessManager::wakeup(&to_wakeup).is_ok();
|
let res = ProcessManager::wakeup(&to_wakeup).is_ok();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -215,7 +224,7 @@ impl WaitQueue {
|
|||||||
while let Some(to_wakeup) = guard.wait_list.pop_front() {
|
while let Some(to_wakeup) = guard.wait_list.pop_front() {
|
||||||
let mut wake = false;
|
let mut wake = false;
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
if to_wakeup.sched_info().state() == state {
|
if to_wakeup.sched_info().inner_lock_read_irqsave().state() == state {
|
||||||
wake = true;
|
wake = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -302,7 +311,7 @@ impl EventWaitQueue {
|
|||||||
|
|
||||||
pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
|
pub fn sleep_unlock_spinlock<T>(&self, events: u64, to_unlock: SpinLockGuard<T>) {
|
||||||
before_sleep_check(1);
|
before_sleep_check(1);
|
||||||
let mut guard = self.wait_list.lock();
|
let mut guard = self.wait_list.lock_irqsave();
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
ProcessManager::mark_sleep(true).unwrap_or_else(|e| {
|
||||||
panic!("sleep error: {:?}", e);
|
panic!("sleep error: {:?}", e);
|
||||||
@ -322,7 +331,9 @@ impl EventWaitQueue {
|
|||||||
/// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒
|
/// 需要注意的是,只要触发了events中的任意一件事件,进程都会被唤醒
|
||||||
pub fn wakeup_any(&self, events: u64) -> usize {
|
pub fn wakeup_any(&self, events: u64) -> usize {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
let _ = self.wait_list.lock().extract_if(|(es, pcb)| {
|
|
||||||
|
let mut wq_guard = self.wait_list.lock_irqsave();
|
||||||
|
wq_guard.retain(|(es, pcb)| {
|
||||||
if *es & events > 0 {
|
if *es & events > 0 {
|
||||||
// 有感兴趣的事件
|
// 有感兴趣的事件
|
||||||
if ProcessManager::wakeup(pcb).is_ok() {
|
if ProcessManager::wakeup(pcb).is_ok() {
|
||||||
@ -346,7 +357,8 @@ impl EventWaitQueue {
|
|||||||
/// 需要注意的是,只有满足所有事件的进程才会被唤醒
|
/// 需要注意的是,只有满足所有事件的进程才会被唤醒
|
||||||
pub fn wakeup(&self, events: u64) -> usize {
|
pub fn wakeup(&self, events: u64) -> usize {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
let _ = self.wait_list.lock().extract_if(|(es, pcb)| {
|
let mut wq_guard = self.wait_list.lock_irqsave();
|
||||||
|
wq_guard.retain(|(es, pcb)| {
|
||||||
if *es == events {
|
if *es == events {
|
||||||
// 有感兴趣的事件
|
// 有感兴趣的事件
|
||||||
if ProcessManager::wakeup(pcb).is_ok() {
|
if ProcessManager::wakeup(pcb).is_ok() {
|
||||||
|
@ -30,11 +30,13 @@ pub mod socket;
|
|||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// @brief 所有网络接口的列表
|
/// 所有网络接口的列表
|
||||||
|
///
|
||||||
|
/// 这个列表在中断上下文会使用到,因此需要irqsave
|
||||||
pub static ref NET_DRIVERS: RwLock<BTreeMap<usize, Arc<dyn NetDriver>>> = RwLock::new(BTreeMap::new());
|
pub static ref NET_DRIVERS: RwLock<BTreeMap<usize, Arc<dyn NetDriver>>> = RwLock::new(BTreeMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 生成网络接口的id (全局自增)
|
/// 生成网络接口的id (全局自增)
|
||||||
pub fn generate_iface_id() -> usize {
|
pub fn generate_iface_id() -> usize {
|
||||||
static IFACE_ID: AtomicUsize = AtomicUsize::new(0);
|
static IFACE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
return IFACE_ID
|
return IFACE_ID
|
||||||
|
@ -41,7 +41,7 @@ pub fn net_init() -> Result<(), SystemError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn dhcp_query() -> Result<(), SystemError> {
|
fn dhcp_query() -> Result<(), SystemError> {
|
||||||
let binding = NET_DRIVERS.write();
|
let binding = NET_DRIVERS.write_irqsave();
|
||||||
|
|
||||||
let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
|
let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
// IMPORTANT: This should be removed in production.
|
// IMPORTANT: This should be removed in production.
|
||||||
dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
|
dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
|
||||||
|
|
||||||
let dhcp_handle = SOCKET_SET.lock().add(dhcp_socket);
|
let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
|
||||||
|
|
||||||
const DHCP_TRY_ROUND: u8 = 10;
|
const DHCP_TRY_ROUND: u8 = 10;
|
||||||
for i in 0..DHCP_TRY_ROUND {
|
for i in 0..DHCP_TRY_ROUND {
|
||||||
kdebug!("DHCP try round: {}", i);
|
kdebug!("DHCP try round: {}", i);
|
||||||
net_face.poll(&mut SOCKET_SET.lock()).ok();
|
net_face.poll(&mut SOCKET_SET.lock_irqsave()).ok();
|
||||||
let mut binding = SOCKET_SET.lock();
|
let mut binding = SOCKET_SET.lock_irqsave();
|
||||||
let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
|
let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
@ -120,12 +120,12 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_ifaces() {
|
pub fn poll_ifaces() {
|
||||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
|
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
|
||||||
if guard.len() == 0 {
|
if guard.len() == 0 {
|
||||||
kwarn!("poll_ifaces: No net driver found!");
|
kwarn!("poll_ifaces: No net driver found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
for (_, iface) in guard.iter() {
|
for (_, iface) in guard.iter() {
|
||||||
iface.poll(&mut sockets).ok();
|
iface.poll(&mut sockets).ok();
|
||||||
}
|
}
|
||||||
@ -140,13 +140,14 @@ pub fn poll_ifaces() {
|
|||||||
pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
|
pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < times {
|
while i < times {
|
||||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
|
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> =
|
||||||
|
NET_DRIVERS.read_irqsave();
|
||||||
if guard.len() == 0 {
|
if guard.len() == 0 {
|
||||||
kwarn!("poll_ifaces: No net driver found!");
|
kwarn!("poll_ifaces: No net driver found!");
|
||||||
// 没有网卡,返回错误
|
// 没有网卡,返回错误
|
||||||
return Err(SystemError::ENODEV);
|
return Err(SystemError::ENODEV);
|
||||||
}
|
}
|
||||||
let sockets = SOCKET_SET.try_lock();
|
let sockets = SOCKET_SET.try_lock_irqsave();
|
||||||
// 加锁失败,继续尝试
|
// 加锁失败,继续尝试
|
||||||
if sockets.is_err() {
|
if sockets.is_err() {
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -171,13 +172,13 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
|
|||||||
/// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
|
/// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
|
||||||
/// @return 没有网卡,返回SystemError::ENODEV
|
/// @return 没有网卡,返回SystemError::ENODEV
|
||||||
pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
|
pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
|
||||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
|
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read_irqsave();
|
||||||
if guard.len() == 0 {
|
if guard.len() == 0 {
|
||||||
kwarn!("poll_ifaces: No net driver found!");
|
kwarn!("poll_ifaces: No net driver found!");
|
||||||
// 没有网卡,返回错误
|
// 没有网卡,返回错误
|
||||||
return Err(SystemError::ENODEV);
|
return Err(SystemError::ENODEV);
|
||||||
}
|
}
|
||||||
let mut sockets = SOCKET_SET.try_lock()?;
|
let mut sockets = SOCKET_SET.try_lock_irqsave()?;
|
||||||
for (_, iface) in guard.iter() {
|
for (_, iface) in guard.iter() {
|
||||||
iface.poll(&mut sockets).ok();
|
iface.poll(&mut sockets).ok();
|
||||||
}
|
}
|
||||||
@ -241,7 +242,7 @@ fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> {
|
|||||||
fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
|
fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
|
||||||
let mut handle_guard = HANDLE_MAP.write_irqsave();
|
let mut handle_guard = HANDLE_MAP.write_irqsave();
|
||||||
let handle_item = handle_guard.get_mut(&handle).unwrap();
|
let handle_item = handle_guard.get_mut(&handle).unwrap();
|
||||||
let mut epitems_guard = handle_item.epitems.try_lock()?;
|
let mut epitems_guard = handle_item.epitems.try_lock_irqsave()?;
|
||||||
|
|
||||||
// 从events拿到epoll相关事件
|
// 从events拿到epoll相关事件
|
||||||
let pollflags = EPollEventType::from_bits_truncate(events);
|
let pollflags = EPollEventType::from_bits_truncate(events);
|
||||||
@ -249,9 +250,9 @@ fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
|
|||||||
// 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓
|
// 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓
|
||||||
if let Some(epitem) = epitems_guard.pop_front() {
|
if let Some(epitem) = epitems_guard.pop_front() {
|
||||||
let epoll = epitem.epoll().upgrade().unwrap();
|
let epoll = epitem.epoll().upgrade().unwrap();
|
||||||
let mut epoll_guard = epoll.try_lock()?;
|
let mut epoll_guard = epoll.try_lock_irqsave()?;
|
||||||
let binding = epitem.clone();
|
let binding = epitem.clone();
|
||||||
let event_guard = binding.event().read();
|
let event_guard = binding.event().read_irqsave();
|
||||||
let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
|
let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
|
||||||
|
|
||||||
// 检查事件合理性以及是否有感兴趣的事件
|
// 检查事件合理性以及是否有感兴趣的事件
|
||||||
|
@ -99,7 +99,7 @@ impl SocketHandleItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown_type_writer(&mut self) -> RwLockWriteGuard<ShutdownType> {
|
pub fn shutdown_type_writer(&mut self) -> RwLockWriteGuard<ShutdownType> {
|
||||||
self.shutdown_type.write()
|
self.shutdown_type.write_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) {
|
pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) {
|
||||||
@ -238,7 +238,7 @@ impl Clone for GlobalSocketHandle {
|
|||||||
|
|
||||||
impl Drop for GlobalSocketHandle {
|
impl Drop for GlobalSocketHandle {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
socket_set_guard.remove(self.0); // 删除的时候,会发送一条FINISH的信息?
|
socket_set_guard.remove(self.0); // 删除的时候,会发送一条FINISH的信息?
|
||||||
drop(socket_set_guard);
|
drop(socket_set_guard);
|
||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
@ -353,7 +353,7 @@ impl RawSocket {
|
|||||||
|
|
||||||
// 把socket添加到socket集合中,并得到socket的句柄
|
// 把socket添加到socket集合中,并得到socket的句柄
|
||||||
let handle: Arc<GlobalSocketHandle> =
|
let handle: Arc<GlobalSocketHandle> =
|
||||||
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
|
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
|
||||||
|
|
||||||
let metadata = SocketMetadata::new(
|
let metadata = SocketMetadata::new(
|
||||||
SocketType::RawSocket,
|
SocketType::RawSocket,
|
||||||
@ -376,7 +376,7 @@ impl Socket for RawSocket {
|
|||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
loop {
|
loop {
|
||||||
// 如何优化这里?
|
// 如何优化这里?
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
||||||
|
|
||||||
match socket.recv_slice(buf) {
|
match socket.recv_slice(buf) {
|
||||||
@ -409,7 +409,7 @@ impl Socket for RawSocket {
|
|||||||
fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
|
fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
|
||||||
// 如果用户发送的数据包,包含IP头,则直接发送
|
// 如果用户发送的数据包,包含IP头,则直接发送
|
||||||
if self.header_included {
|
if self.header_included {
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
||||||
match socket.send_slice(buf) {
|
match socket.send_slice(buf) {
|
||||||
Ok(_len) => {
|
Ok(_len) => {
|
||||||
@ -423,12 +423,12 @@ impl Socket for RawSocket {
|
|||||||
// 如果用户发送的数据包,不包含IP头,则需要自己构造IP头
|
// 如果用户发送的数据包,不包含IP头,则需要自己构造IP头
|
||||||
|
|
||||||
if let Some(Endpoint::Ip(Some(endpoint))) = to {
|
if let Some(Endpoint::Ip(Some(endpoint))) = to {
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket: &mut raw::Socket =
|
let socket: &mut raw::Socket =
|
||||||
socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
||||||
|
|
||||||
// 暴力解决方案:只考虑0号网卡。 TODO:考虑多网卡的情况!!!
|
// 暴力解决方案:只考虑0号网卡。 TODO:考虑多网卡的情况!!!
|
||||||
let iface = NET_DRIVERS.read().get(&0).unwrap().clone();
|
let iface = NET_DRIVERS.read_irqsave().get(&0).unwrap().clone();
|
||||||
|
|
||||||
// 构造IP头
|
// 构造IP头
|
||||||
let ipv4_src_addr: Option<smoltcp::wire::Ipv4Address> =
|
let ipv4_src_addr: Option<smoltcp::wire::Ipv4Address> =
|
||||||
@ -535,7 +535,7 @@ impl UdpSocket {
|
|||||||
|
|
||||||
// 把socket添加到socket集合中,并得到socket的句柄
|
// 把socket添加到socket集合中,并得到socket的句柄
|
||||||
let handle: Arc<GlobalSocketHandle> =
|
let handle: Arc<GlobalSocketHandle> =
|
||||||
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
|
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
|
||||||
|
|
||||||
let metadata = SocketMetadata::new(
|
let metadata = SocketMetadata::new(
|
||||||
SocketType::UdpSocket,
|
SocketType::UdpSocket,
|
||||||
@ -579,7 +579,7 @@ impl Socket for UdpSocket {
|
|||||||
loop {
|
loop {
|
||||||
// kdebug!("Wait22 to Read");
|
// kdebug!("Wait22 to Read");
|
||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
|
||||||
|
|
||||||
// kdebug!("Wait to Read");
|
// kdebug!("Wait to Read");
|
||||||
@ -616,7 +616,7 @@ impl Socket for UdpSocket {
|
|||||||
};
|
};
|
||||||
// kdebug!("udp write: remote = {:?}", remote_endpoint);
|
// kdebug!("udp write: remote = {:?}", remote_endpoint);
|
||||||
|
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<udp::Socket>(self.handle.0);
|
||||||
// kdebug!("is open()={}", socket.is_open());
|
// kdebug!("is open()={}", socket.is_open());
|
||||||
// kdebug!("socket endpoint={:?}", socket.endpoint());
|
// kdebug!("socket endpoint={:?}", socket.endpoint());
|
||||||
@ -660,14 +660,14 @@ impl Socket for UdpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bind(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
|
fn bind(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get_mut::<udp::Socket>(self.handle.0);
|
let socket = sockets.get_mut::<udp::Socket>(self.handle.0);
|
||||||
// kdebug!("UDP Bind to {:?}", endpoint);
|
// kdebug!("UDP Bind to {:?}", endpoint);
|
||||||
return self.do_bind(socket, endpoint);
|
return self.do_bind(socket, endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) -> EPollEventType {
|
fn poll(&self) -> EPollEventType {
|
||||||
let sockets = SOCKET_SET.lock();
|
let sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get::<udp::Socket>(self.handle.0);
|
let socket = sockets.get::<udp::Socket>(self.handle.0);
|
||||||
|
|
||||||
return SocketPollMethod::udp_poll(
|
return SocketPollMethod::udp_poll(
|
||||||
@ -708,7 +708,7 @@ impl Socket for UdpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn endpoint(&self) -> Option<Endpoint> {
|
fn endpoint(&self) -> Option<Endpoint> {
|
||||||
let sockets = SOCKET_SET.lock();
|
let sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get::<udp::Socket>(self.handle.0);
|
let socket = sockets.get::<udp::Socket>(self.handle.0);
|
||||||
let listen_endpoint = socket.endpoint();
|
let listen_endpoint = socket.endpoint();
|
||||||
|
|
||||||
@ -773,7 +773,7 @@ impl TcpSocket {
|
|||||||
|
|
||||||
// 把socket添加到socket集合中,并得到socket的句柄
|
// 把socket添加到socket集合中,并得到socket的句柄
|
||||||
let handle: Arc<GlobalSocketHandle> =
|
let handle: Arc<GlobalSocketHandle> =
|
||||||
GlobalSocketHandle::new(SOCKET_SET.lock().add(socket));
|
GlobalSocketHandle::new(SOCKET_SET.lock_irqsave().add(socket));
|
||||||
|
|
||||||
let metadata = SocketMetadata::new(
|
let metadata = SocketMetadata::new(
|
||||||
SocketType::TcpSocket,
|
SocketType::TcpSocket,
|
||||||
@ -833,7 +833,7 @@ impl Socket for TcpSocket {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
// 如果socket已经关闭,返回错误
|
// 如果socket已经关闭,返回错误
|
||||||
@ -898,7 +898,7 @@ impl Socket for TcpSocket {
|
|||||||
{
|
{
|
||||||
return Err(SystemError::ENOTCONN);
|
return Err(SystemError::ENOTCONN);
|
||||||
}
|
}
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
if socket.is_open() {
|
if socket.is_open() {
|
||||||
@ -923,7 +923,7 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) -> EPollEventType {
|
fn poll(&self) -> EPollEventType {
|
||||||
let mut socket_set_guard = SOCKET_SET.lock();
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
||||||
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = socket_set_guard.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
return SocketPollMethod::tcp_poll(
|
return SocketPollMethod::tcp_poll(
|
||||||
@ -937,7 +937,7 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn connect(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
|
fn connect(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
if let Endpoint::Ip(Some(ip)) = endpoint {
|
if let Endpoint::Ip(Some(ip)) = endpoint {
|
||||||
@ -946,7 +946,7 @@ impl Socket for TcpSocket {
|
|||||||
PORT_MANAGER.bind_port(self.metadata.socket_type, temp_port, self.handle.clone())?;
|
PORT_MANAGER.bind_port(self.metadata.socket_type, temp_port, self.handle.clone())?;
|
||||||
|
|
||||||
// kdebug!("temp_port: {}", temp_port);
|
// kdebug!("temp_port: {}", temp_port);
|
||||||
let iface: Arc<dyn NetDriver> = NET_DRIVERS.write().get(&0).unwrap().clone();
|
let iface: Arc<dyn NetDriver> = NET_DRIVERS.write_irqsave().get(&0).unwrap().clone();
|
||||||
let mut inner_iface = iface.inner_iface().lock();
|
let mut inner_iface = iface.inner_iface().lock();
|
||||||
// kdebug!("to connect: {ip:?}");
|
// kdebug!("to connect: {ip:?}");
|
||||||
|
|
||||||
@ -958,7 +958,7 @@ impl Socket for TcpSocket {
|
|||||||
drop(sockets);
|
drop(sockets);
|
||||||
loop {
|
loop {
|
||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
match socket.state() {
|
match socket.state() {
|
||||||
@ -1001,7 +1001,7 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let local_endpoint = self.local_endpoint.ok_or(SystemError::EINVAL)?;
|
let local_endpoint = self.local_endpoint.ok_or(SystemError::EINVAL)?;
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
if socket.is_listening() {
|
if socket.is_listening() {
|
||||||
@ -1044,7 +1044,7 @@ impl Socket for TcpSocket {
|
|||||||
// kdebug!("tcp accept: poll_ifaces()");
|
// kdebug!("tcp accept: poll_ifaces()");
|
||||||
poll_ifaces();
|
poll_ifaces();
|
||||||
|
|
||||||
let mut sockets = SOCKET_SET.lock();
|
let mut sockets = SOCKET_SET.lock_irqsave();
|
||||||
|
|
||||||
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get_mut::<tcp::Socket>(self.handle.0);
|
||||||
|
|
||||||
@ -1126,7 +1126,7 @@ impl Socket for TcpSocket {
|
|||||||
self.local_endpoint.clone().map(|x| Endpoint::Ip(Some(x)));
|
self.local_endpoint.clone().map(|x| Endpoint::Ip(Some(x)));
|
||||||
|
|
||||||
if result.is_none() {
|
if result.is_none() {
|
||||||
let sockets = SOCKET_SET.lock();
|
let sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get::<tcp::Socket>(self.handle.0);
|
||||||
if let Some(ep) = socket.local_endpoint() {
|
if let Some(ep) = socket.local_endpoint() {
|
||||||
result = Some(Endpoint::Ip(Some(ep)));
|
result = Some(Endpoint::Ip(Some(ep)));
|
||||||
@ -1136,7 +1136,7 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn peer_endpoint(&self) -> Option<Endpoint> {
|
fn peer_endpoint(&self) -> Option<Endpoint> {
|
||||||
let sockets = SOCKET_SET.lock();
|
let sockets = SOCKET_SET.lock_irqsave();
|
||||||
let socket = sockets.get::<tcp::Socket>(self.handle.0);
|
let socket = sockets.get::<tcp::Socket>(self.handle.0);
|
||||||
return socket.remote_endpoint().map(|x| Endpoint::Ip(Some(x)));
|
return socket.remote_endpoint().map(|x| Endpoint::Ip(Some(x)));
|
||||||
}
|
}
|
||||||
|
@ -154,8 +154,9 @@ fn do_wait(kwo: &mut KernelWaitOption) -> Result<usize, SystemError> {
|
|||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
for pid in rd_childen.iter() {
|
for pid in rd_childen.iter() {
|
||||||
let pcb = ProcessManager::find(*pid).ok_or(SystemError::ECHILD)?;
|
let pcb = ProcessManager::find(*pid).ok_or(SystemError::ECHILD)?;
|
||||||
if pcb.sched_info().state().is_exited() {
|
let state = pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
kwo.ret_status = pcb.sched_info().state().exit_code().unwrap() as i32;
|
if state.is_exited() {
|
||||||
|
kwo.ret_status = state.exit_code().unwrap() as i32;
|
||||||
drop(pcb);
|
drop(pcb);
|
||||||
unsafe { ProcessManager::release(pid.clone()) };
|
unsafe { ProcessManager::release(pid.clone()) };
|
||||||
return Ok(pid.clone().into());
|
return Ok(pid.clone().into());
|
||||||
@ -179,7 +180,7 @@ fn do_waitpid(
|
|||||||
child_pcb: Arc<ProcessControlBlock>,
|
child_pcb: Arc<ProcessControlBlock>,
|
||||||
kwo: &mut KernelWaitOption,
|
kwo: &mut KernelWaitOption,
|
||||||
) -> Option<Result<usize, SystemError>> {
|
) -> Option<Result<usize, SystemError>> {
|
||||||
let state = child_pcb.sched_info().state();
|
let state = child_pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
// 获取退出码
|
// 获取退出码
|
||||||
match state {
|
match state {
|
||||||
ProcessState::Runnable => {
|
ProcessState::Runnable => {
|
||||||
|
@ -159,6 +159,7 @@ impl ProcessManager {
|
|||||||
let new_kstack: KernelStack = KernelStack::new()?;
|
let new_kstack: KernelStack = KernelStack::new()?;
|
||||||
|
|
||||||
let name = current_pcb.basic().name().to_string();
|
let name = current_pcb.basic().name().to_string();
|
||||||
|
|
||||||
let pcb = ProcessControlBlock::new(name, new_kstack);
|
let pcb = ProcessControlBlock::new(name, new_kstack);
|
||||||
|
|
||||||
let mut args = KernelCloneArgs::new();
|
let mut args = KernelCloneArgs::new();
|
||||||
@ -166,7 +167,6 @@ impl ProcessManager {
|
|||||||
args.exit_signal = Signal::SIGCHLD;
|
args.exit_signal = Signal::SIGCHLD;
|
||||||
|
|
||||||
Self::copy_process(¤t_pcb, &pcb, args, current_trapframe)?;
|
Self::copy_process(¤t_pcb, &pcb, args, current_trapframe)?;
|
||||||
|
|
||||||
ProcessManager::add_pcb(pcb.clone());
|
ProcessManager::add_pcb(pcb.clone());
|
||||||
|
|
||||||
// 向procfs注册进程
|
// 向procfs注册进程
|
||||||
@ -232,7 +232,7 @@ impl ProcessManager {
|
|||||||
unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
|
unsafe { new_pcb.basic_mut().set_user_vm(Some(old_address_space)) };
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let new_address_space = old_address_space.write().try_clone().unwrap_or_else(|e| {
|
let new_address_space = old_address_space.write_irqsave().try_clone().unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
"copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
|
"copy_mm: Failed to clone address space of current process, current pid: [{:?}], new pid: [{:?}]. Error: {:?}",
|
||||||
current_pcb.pid(), new_pcb.pid(), e
|
current_pcb.pid(), new_pcb.pid(), e
|
||||||
@ -242,6 +242,7 @@ impl ProcessManager {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn copy_files(
|
fn copy_files(
|
||||||
clone_flags: &CloneFlags,
|
clone_flags: &CloneFlags,
|
||||||
current_pcb: &Arc<ProcessControlBlock>,
|
current_pcb: &Arc<ProcessControlBlock>,
|
||||||
@ -274,7 +275,8 @@ impl ProcessManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
|
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
|
||||||
(*new_pcb.sig_struct()).handlers = current_pcb.sig_struct().handlers.clone();
|
(*new_pcb.sig_struct_irqsave()).handlers =
|
||||||
|
current_pcb.sig_struct_irqsave().handlers.clone();
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -288,8 +290,8 @@ impl ProcessManager {
|
|||||||
/// ## 参数
|
/// ## 参数
|
||||||
///
|
///
|
||||||
/// - clone_flags 标志位
|
/// - clone_flags 标志位
|
||||||
/// - des_pcb 目标pcb
|
/// - current_pcb 拷贝源pcb
|
||||||
/// - src_pcb 拷贝源pcb
|
/// - pcb 目标pcb
|
||||||
///
|
///
|
||||||
/// ## return
|
/// ## return
|
||||||
/// - 发生错误时返回Err(SystemError)
|
/// - 发生错误时返回Err(SystemError)
|
||||||
@ -350,7 +352,7 @@ impl ProcessManager {
|
|||||||
|
|
||||||
// 克隆架构相关
|
// 克隆架构相关
|
||||||
let guard = current_pcb.arch_info_irqsave();
|
let guard = current_pcb.arch_info_irqsave();
|
||||||
pcb.arch_info().clone_from(&guard);
|
unsafe { pcb.arch_info().clone_from(&guard) };
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
// 为内核线程设置WorkerPrivate
|
// 为内核线程设置WorkerPrivate
|
||||||
|
@ -291,7 +291,6 @@ impl KernelThreadMechanism {
|
|||||||
CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
|
CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
|
||||||
)
|
)
|
||||||
.expect("Failed to create kthread daemon");
|
.expect("Failed to create kthread daemon");
|
||||||
|
|
||||||
let pcb = ProcessManager::find(kthreadd_pid).unwrap();
|
let pcb = ProcessManager::find(kthreadd_pid).unwrap();
|
||||||
ProcessManager::wakeup(&pcb).expect("Failed to wakeup kthread daemon");
|
ProcessManager::wakeup(&pcb).expect("Failed to wakeup kthread daemon");
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -379,7 +378,7 @@ impl KernelThreadMechanism {
|
|||||||
// 忙等目标内核线程退出
|
// 忙等目标内核线程退出
|
||||||
// todo: 使用completion机制优化这里
|
// todo: 使用completion机制优化这里
|
||||||
loop {
|
loop {
|
||||||
if let ProcessState::Exited(code) = pcb.sched_info().state() {
|
if let ProcessState::Exited(code) = pcb.sched_info().inner_lock_read_irqsave().state() {
|
||||||
return Ok(code);
|
return Ok(code);
|
||||||
}
|
}
|
||||||
spin_loop();
|
spin_loop();
|
||||||
|
@ -112,7 +112,7 @@ impl ProcessManager {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
};
|
};
|
||||||
|
|
||||||
ALL_PROCESS.lock().replace(HashMap::new());
|
ALL_PROCESS.lock_irqsave().replace(HashMap::new());
|
||||||
Self::arch_init();
|
Self::arch_init();
|
||||||
kdebug!("process arch init done.");
|
kdebug!("process arch init done.");
|
||||||
Self::init_idle();
|
Self::init_idle();
|
||||||
@ -164,7 +164,7 @@ impl ProcessManager {
|
|||||||
///
|
///
|
||||||
/// 如果找到了对应的进程,那么返回该进程的pcb,否则返回None
|
/// 如果找到了对应的进程,那么返回该进程的pcb,否则返回None
|
||||||
pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> {
|
pub fn find(pid: Pid) -> Option<Arc<ProcessControlBlock>> {
|
||||||
return ALL_PROCESS.lock().as_ref()?.get(&pid).cloned();
|
return ALL_PROCESS.lock_irqsave().as_ref()?.get(&pid).cloned();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 向系统中添加一个进程的pcb
|
/// 向系统中添加一个进程的pcb
|
||||||
@ -178,7 +178,7 @@ impl ProcessManager {
|
|||||||
/// 无
|
/// 无
|
||||||
pub fn add_pcb(pcb: Arc<ProcessControlBlock>) {
|
pub fn add_pcb(pcb: Arc<ProcessControlBlock>) {
|
||||||
ALL_PROCESS
|
ALL_PROCESS
|
||||||
.lock()
|
.lock_irqsave()
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(pcb.pid(), pcb.clone());
|
.insert(pcb.pid(), pcb.clone());
|
||||||
@ -187,9 +187,9 @@ impl ProcessManager {
|
|||||||
/// 唤醒一个进程
|
/// 唤醒一个进程
|
||||||
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
|
pub fn wakeup(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
|
||||||
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
let state = pcb.sched_info().state();
|
let state = pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
if state.is_blocked() {
|
if state.is_blocked() {
|
||||||
let mut writer: RwLockWriteGuard<'_, ProcessSchedulerInfo> = pcb.sched_info_mut();
|
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
|
||||||
let state = writer.state();
|
let state = writer.state();
|
||||||
if state.is_blocked() {
|
if state.is_blocked() {
|
||||||
writer.set_state(ProcessState::Runnable);
|
writer.set_state(ProcessState::Runnable);
|
||||||
@ -213,9 +213,9 @@ impl ProcessManager {
|
|||||||
/// 唤醒暂停的进程
|
/// 唤醒暂停的进程
|
||||||
pub fn wakeup_stop(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
|
pub fn wakeup_stop(pcb: &Arc<ProcessControlBlock>) -> Result<(), SystemError> {
|
||||||
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
let state = pcb.sched_info().state();
|
let state = pcb.sched_info().inner_lock_read_irqsave().state();
|
||||||
if let ProcessState::Stopped = state {
|
if let ProcessState::Stopped = state {
|
||||||
let mut writer = pcb.sched_info_mut();
|
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
|
||||||
let state = writer.state();
|
let state = writer.state();
|
||||||
if let ProcessState::Stopped = state {
|
if let ProcessState::Stopped = state {
|
||||||
writer.set_state(ProcessState::Runnable);
|
writer.set_state(ProcessState::Runnable);
|
||||||
@ -251,7 +251,7 @@ impl ProcessManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let mut writer = pcb.sched_info_mut_irqsave();
|
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
|
||||||
if !matches!(writer.state(), ProcessState::Exited(_)) {
|
if !matches!(writer.state(), ProcessState::Exited(_)) {
|
||||||
writer.set_state(ProcessState::Blocked(interruptable));
|
writer.set_state(ProcessState::Blocked(interruptable));
|
||||||
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
|
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
|
||||||
@ -276,7 +276,7 @@ impl ProcessManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let mut writer = pcb.sched_info_mut_irqsave();
|
let mut writer = pcb.sched_info().inner_lock_write_irqsave();
|
||||||
if !matches!(writer.state(), ProcessState::Exited(_)) {
|
if !matches!(writer.state(), ProcessState::Exited(_)) {
|
||||||
writer.set_state(ProcessState::Stopped);
|
writer.set_state(ProcessState::Stopped);
|
||||||
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
|
pcb.flags().insert(ProcessFlags::NEED_SCHEDULE);
|
||||||
@ -321,10 +321,10 @@ impl ProcessManager {
|
|||||||
/// - `exit_code` : 进程的退出码
|
/// - `exit_code` : 进程的退出码
|
||||||
pub fn exit(exit_code: usize) -> ! {
|
pub fn exit(exit_code: usize) -> ! {
|
||||||
// 关中断
|
// 关中断
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
unsafe { CurrentIrqArch::interrupt_disable() };
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
pcb.sched_info
|
pcb.sched_info
|
||||||
.write()
|
.inner_lock_write_irqsave()
|
||||||
.set_state(ProcessState::Exited(exit_code));
|
.set_state(ProcessState::Exited(exit_code));
|
||||||
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
|
pcb.wait_queue.wakeup(Some(ProcessState::Blocked(true)));
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ impl ProcessManager {
|
|||||||
unsafe { pcb.basic_mut().set_user_vm(None) };
|
unsafe { pcb.basic_mut().set_user_vm(None) };
|
||||||
drop(pcb);
|
drop(pcb);
|
||||||
ProcessManager::exit_notify();
|
ProcessManager::exit_notify();
|
||||||
drop(irq_guard);
|
unsafe { CurrentIrqArch::interrupt_enable() };
|
||||||
|
|
||||||
sched();
|
sched();
|
||||||
loop {}
|
loop {}
|
||||||
@ -373,7 +373,7 @@ impl ProcessManager {
|
|||||||
// panic!()
|
// panic!()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ALL_PROCESS.lock().as_mut().unwrap().remove(&pid);
|
ALL_PROCESS.lock_irqsave().as_mut().unwrap().remove(&pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ pub struct ProcessControlBlock {
|
|||||||
syscall_stack: RwLock<KernelStack>,
|
syscall_stack: RwLock<KernelStack>,
|
||||||
|
|
||||||
/// 与调度相关的信息
|
/// 与调度相关的信息
|
||||||
sched_info: RwLock<ProcessSchedulerInfo>,
|
sched_info: ProcessSchedulerInfo,
|
||||||
/// 与处理器架构相关的信息
|
/// 与处理器架构相关的信息
|
||||||
arch_info: SpinLock<ArchPCBInfo>,
|
arch_info: SpinLock<ArchPCBInfo>,
|
||||||
/// 与信号处理相关的信息(似乎可以是无锁的)
|
/// 与信号处理相关的信息(似乎可以是无锁的)
|
||||||
@ -592,6 +592,7 @@ impl ProcessControlBlock {
|
|||||||
return Self::do_create_pcb(name, kstack, true);
|
return Self::do_create_pcb(name, kstack, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> {
|
fn do_create_pcb(name: String, kstack: KernelStack, is_idle: bool) -> Arc<Self> {
|
||||||
let (pid, ppid, cwd) = if is_idle {
|
let (pid, ppid, cwd) = if is_idle {
|
||||||
(Pid(0), Pid(0), "/".to_string())
|
(Pid(0), Pid(0), "/".to_string())
|
||||||
@ -624,7 +625,7 @@ impl ProcessControlBlock {
|
|||||||
sched_info,
|
sched_info,
|
||||||
arch_info,
|
arch_info,
|
||||||
sig_info: RwLock::new(ProcessSignalInfo::default()),
|
sig_info: RwLock::new(ProcessSignalInfo::default()),
|
||||||
sig_struct: SpinLock::new(SignalStruct::default()),
|
sig_struct: SpinLock::new(SignalStruct::new()),
|
||||||
exit_signal: AtomicSignal::new(Signal::SIGCHLD),
|
exit_signal: AtomicSignal::new(Signal::SIGCHLD),
|
||||||
parent_pcb: RwLock::new(ppcb.clone()),
|
parent_pcb: RwLock::new(ppcb.clone()),
|
||||||
real_parent_pcb: RwLock::new(ppcb),
|
real_parent_pcb: RwLock::new(ppcb),
|
||||||
@ -657,7 +658,7 @@ impl ProcessControlBlock {
|
|||||||
// 将当前pcb加入父进程的子进程哈希表中
|
// 将当前pcb加入父进程的子进程哈希表中
|
||||||
if pcb.pid() > Pid(1) {
|
if pcb.pid() > Pid(1) {
|
||||||
if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() {
|
if let Some(ppcb_arc) = pcb.parent_pcb.read().upgrade() {
|
||||||
let mut children = ppcb_arc.children.write();
|
let mut children = ppcb_arc.children.write_irqsave();
|
||||||
children.push(pcb.pid());
|
children.push(pcb.pid());
|
||||||
} else {
|
} else {
|
||||||
panic!("parent pcb is None");
|
panic!("parent pcb is None");
|
||||||
@ -702,6 +703,8 @@ impl ProcessControlBlock {
|
|||||||
return self.flags.get_mut();
|
return self.flags.get_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 请注意,这个值能在中断上下文中读取,但不能被中断上下文修改
|
||||||
|
/// 否则会导致死锁
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
|
pub fn basic(&self) -> RwLockReadGuard<ProcessBasicInfo> {
|
||||||
return self.basic.read();
|
return self.basic.read();
|
||||||
@ -714,19 +717,28 @@ impl ProcessControlBlock {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn basic_mut(&self) -> RwLockWriteGuard<ProcessBasicInfo> {
|
pub fn basic_mut(&self) -> RwLockWriteGuard<ProcessBasicInfo> {
|
||||||
return self.basic.write();
|
return self.basic.write_irqsave();
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> {
|
|
||||||
return self.arch_info.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # 获取arch info的锁,同时关闭中断
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn arch_info_irqsave(&self) -> SpinLockGuard<ArchPCBInfo> {
|
pub fn arch_info_irqsave(&self) -> SpinLockGuard<ArchPCBInfo> {
|
||||||
return self.arch_info.lock_irqsave();
|
return self.arch_info.lock_irqsave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # 获取arch info的锁,但是不关闭中断
|
||||||
|
///
|
||||||
|
/// 由于arch info在进程切换的时候会使用到,
|
||||||
|
/// 因此在中断上下文外,获取arch info 而不irqsave是不安全的.
|
||||||
|
///
|
||||||
|
/// 只能在以下情况下使用这个函数:
|
||||||
|
/// - 在中断上下文中(中断已经禁用),获取arch info的锁。
|
||||||
|
/// - 刚刚创建新的pcb
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn arch_info(&self) -> SpinLockGuard<ArchPCBInfo> {
|
||||||
|
return self.arch_info.lock();
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn kernel_stack(&self) -> RwLockReadGuard<KernelStack> {
|
pub fn kernel_stack(&self) -> RwLockReadGuard<KernelStack> {
|
||||||
return self.kernel_stack.read();
|
return self.kernel_stack.read();
|
||||||
@ -739,48 +751,8 @@ impl ProcessControlBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn sched_info(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
|
pub fn sched_info(&self) -> &ProcessSchedulerInfo {
|
||||||
return self.sched_info.read();
|
return &self.sched_info;
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn try_sched_info(&self, times: u8) -> Option<RwLockReadGuard<ProcessSchedulerInfo>> {
|
|
||||||
for _ in 0..times {
|
|
||||||
if let Some(r) = self.sched_info.try_read() {
|
|
||||||
return Some(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sched_info_irqsave(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
|
|
||||||
return self.sched_info.read_irqsave();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sched_info_try_upgradeable_irqsave(
|
|
||||||
&self,
|
|
||||||
times: u8,
|
|
||||||
) -> Option<RwLockUpgradableGuard<ProcessSchedulerInfo>> {
|
|
||||||
for _ in 0..times {
|
|
||||||
if let Some(r) = self.sched_info.try_upgradeable_read_irqsave() {
|
|
||||||
return Some(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sched_info_mut(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
|
|
||||||
return self.sched_info.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn sched_info_mut_irqsave(&self) -> RwLockWriteGuard<ProcessSchedulerInfo> {
|
|
||||||
return self.sched_info.write_irqsave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -877,7 +849,7 @@ impl ProcessControlBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sig_info_mut(&self) -> RwLockWriteGuard<ProcessSignalInfo> {
|
pub fn sig_info_mut(&self) -> RwLockWriteGuard<ProcessSignalInfo> {
|
||||||
self.sig_info.write()
|
self.sig_info.write_irqsave()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
|
pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
|
||||||
@ -904,7 +876,7 @@ impl ProcessControlBlock {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sig_struct_irq(&self) -> SpinLockGuard<SignalStruct> {
|
pub fn sig_struct_irqsave(&self) -> SpinLockGuard<SignalStruct> {
|
||||||
self.sig_struct.lock_irqsave()
|
self.sig_struct.lock_irqsave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -971,6 +943,7 @@ pub struct ProcessBasicInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessBasicInfo {
|
impl ProcessBasicInfo {
|
||||||
|
#[inline(never)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
pgid: Pid,
|
pgid: Pid,
|
||||||
ppid: Pid,
|
ppid: Pid,
|
||||||
@ -1036,11 +1009,7 @@ pub struct ProcessSchedulerInfo {
|
|||||||
/// 如果当前进程等待被迁移到另一个cpu核心上(也就是flags中的PF_NEED_MIGRATE被置位),
|
/// 如果当前进程等待被迁移到另一个cpu核心上(也就是flags中的PF_NEED_MIGRATE被置位),
|
||||||
/// 该字段存储要被迁移到的目标处理器核心号
|
/// 该字段存储要被迁移到的目标处理器核心号
|
||||||
migrate_to: AtomicI32,
|
migrate_to: AtomicI32,
|
||||||
|
inner_locked: RwLock<InnerSchedInfo>,
|
||||||
/// 当前进程的状态
|
|
||||||
state: ProcessState,
|
|
||||||
/// 进程的调度策略
|
|
||||||
sched_policy: SchedPolicy,
|
|
||||||
/// 进程的调度优先级
|
/// 进程的调度优先级
|
||||||
priority: SchedPriority,
|
priority: SchedPriority,
|
||||||
/// 当前进程的虚拟运行时间
|
/// 当前进程的虚拟运行时间
|
||||||
@ -1049,21 +1018,46 @@ pub struct ProcessSchedulerInfo {
|
|||||||
rt_time_slice: AtomicIsize,
|
rt_time_slice: AtomicIsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InnerSchedInfo {
|
||||||
|
/// 当前进程的状态
|
||||||
|
state: ProcessState,
|
||||||
|
/// 进程的调度策略
|
||||||
|
sched_policy: SchedPolicy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InnerSchedInfo {
|
||||||
|
pub fn state(&self) -> ProcessState {
|
||||||
|
return self.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_state(&mut self, state: ProcessState) {
|
||||||
|
self.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn policy(&self) -> SchedPolicy {
|
||||||
|
return self.sched_policy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ProcessSchedulerInfo {
|
impl ProcessSchedulerInfo {
|
||||||
pub fn new(on_cpu: Option<u32>) -> RwLock<Self> {
|
#[inline(never)]
|
||||||
|
pub fn new(on_cpu: Option<u32>) -> Self {
|
||||||
let cpu_id = match on_cpu {
|
let cpu_id = match on_cpu {
|
||||||
Some(cpu_id) => cpu_id as i32,
|
Some(cpu_id) => cpu_id as i32,
|
||||||
None => -1,
|
None => -1,
|
||||||
};
|
};
|
||||||
return RwLock::new(Self {
|
return Self {
|
||||||
on_cpu: AtomicI32::new(cpu_id),
|
on_cpu: AtomicI32::new(cpu_id),
|
||||||
migrate_to: AtomicI32::new(-1),
|
migrate_to: AtomicI32::new(-1),
|
||||||
state: ProcessState::Blocked(false),
|
inner_locked: RwLock::new(InnerSchedInfo {
|
||||||
sched_policy: SchedPolicy::CFS,
|
state: ProcessState::Blocked(false),
|
||||||
|
sched_policy: SchedPolicy::CFS,
|
||||||
|
}),
|
||||||
virtual_runtime: AtomicIsize::new(0),
|
virtual_runtime: AtomicIsize::new(0),
|
||||||
rt_time_slice: AtomicIsize::new(0),
|
rt_time_slice: AtomicIsize::new(0),
|
||||||
priority: SchedPriority::new(100).unwrap(),
|
priority: SchedPriority::new(100).unwrap(),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_cpu(&self) -> Option<u32> {
|
pub fn on_cpu(&self) -> Option<u32> {
|
||||||
@ -1100,16 +1094,38 @@ impl ProcessSchedulerInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> ProcessState {
|
pub fn inner_lock_write_irqsave(&self) -> RwLockWriteGuard<InnerSchedInfo> {
|
||||||
return self.state;
|
return self.inner_locked.write_irqsave();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_state(&mut self, state: ProcessState) {
|
pub fn inner_lock_read_irqsave(&self) -> RwLockReadGuard<InnerSchedInfo> {
|
||||||
self.state = state;
|
return self.inner_locked.read_irqsave();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn policy(&self) -> SchedPolicy {
|
pub fn inner_lock_try_read_irqsave(
|
||||||
return self.sched_policy;
|
&self,
|
||||||
|
times: u8,
|
||||||
|
) -> Option<RwLockReadGuard<InnerSchedInfo>> {
|
||||||
|
for _ in 0..times {
|
||||||
|
if let Some(r) = self.inner_locked.try_read_irqsave() {
|
||||||
|
return Some(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inner_lock_try_upgradable_read_irqsave(
|
||||||
|
&self,
|
||||||
|
times: u8,
|
||||||
|
) -> Option<RwLockUpgradableGuard<InnerSchedInfo>> {
|
||||||
|
for _ in 0..times {
|
||||||
|
if let Some(r) = self.inner_locked.try_upgradeable_read_irqsave() {
|
||||||
|
return Some(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn virtual_runtime(&self) -> isize {
|
pub fn virtual_runtime(&self) -> isize {
|
||||||
|
@ -9,7 +9,6 @@ use crate::{
|
|||||||
kBUG,
|
kBUG,
|
||||||
libs::{
|
libs::{
|
||||||
rbtree::RBTree,
|
rbtree::RBTree,
|
||||||
rwlock::RwLockReadGuard,
|
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
},
|
},
|
||||||
process::{
|
process::{
|
||||||
@ -150,16 +149,13 @@ impl SchedulerCFS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 时钟中断到来时,由sched的core模块中的函数,调用本函数,更新CFS进程的可执行时间
|
/// @brief 时钟中断到来时,由sched的core模块中的函数,调用本函数,更新CFS进程的可执行时间
|
||||||
pub fn timer_update_jiffies(
|
pub fn timer_update_jiffies(&mut self, sched_info: &ProcessSchedulerInfo) {
|
||||||
&mut self,
|
|
||||||
sched_info_guard: &RwLockReadGuard<'_, ProcessSchedulerInfo>,
|
|
||||||
) {
|
|
||||||
let current_cpu_queue: &mut CFSQueue = self.cpu_queue[smp_get_processor_id() as usize];
|
let current_cpu_queue: &mut CFSQueue = self.cpu_queue[smp_get_processor_id() as usize];
|
||||||
// todo: 引入调度周期以及所有进程的优先权进行计算,然后设置进程的可执行时间
|
// todo: 引入调度周期以及所有进程的优先权进行计算,然后设置进程的可执行时间
|
||||||
|
|
||||||
let mut queue = None;
|
let mut queue = None;
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
if let Ok(q) = current_cpu_queue.locked_queue.try_lock() {
|
if let Ok(q) = current_cpu_queue.locked_queue.try_lock_irqsave() {
|
||||||
queue = Some(q);
|
queue = Some(q);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -179,13 +175,13 @@ impl SchedulerCFS {
|
|||||||
drop(queue);
|
drop(queue);
|
||||||
|
|
||||||
// 更新当前进程的虚拟运行时间
|
// 更新当前进程的虚拟运行时间
|
||||||
sched_info_guard.increase_virtual_runtime(1);
|
sched_info.increase_virtual_runtime(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief 将进程加入cpu的cfs调度队列,并且重设其虚拟运行时间为当前队列的最小值
|
/// @brief 将进程加入cpu的cfs调度队列,并且重设其虚拟运行时间为当前队列的最小值
|
||||||
pub fn enqueue_reset_vruntime(&mut self, pcb: Arc<ProcessControlBlock>) {
|
pub fn enqueue_reset_vruntime(&mut self, pcb: Arc<ProcessControlBlock>) {
|
||||||
let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap() as usize];
|
let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap() as usize];
|
||||||
let queue = cpu_queue.locked_queue.lock();
|
let queue = cpu_queue.locked_queue.lock_irqsave();
|
||||||
if queue.len() > 0 {
|
if queue.len() > 0 {
|
||||||
pcb.sched_info()
|
pcb.sched_info()
|
||||||
.set_virtual_runtime(CFSQueue::min_vruntime(&queue).unwrap_or(0) as isize)
|
.set_virtual_runtime(CFSQueue::min_vruntime(&queue).unwrap_or(0) as isize)
|
||||||
@ -202,7 +198,7 @@ impl SchedulerCFS {
|
|||||||
}
|
}
|
||||||
/// 获取某个cpu的运行队列中的进程数
|
/// 获取某个cpu的运行队列中的进程数
|
||||||
pub fn get_cfs_queue_len(&mut self, cpu_id: u32) -> usize {
|
pub fn get_cfs_queue_len(&mut self, cpu_id: u32) -> usize {
|
||||||
let queue = self.cpu_queue[cpu_id as usize].locked_queue.lock();
|
let queue = self.cpu_queue[cpu_id as usize].locked_queue.lock_irqsave();
|
||||||
return CFSQueue::get_cfs_queue_size(&queue);
|
return CFSQueue::get_cfs_queue_size(&queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,13 +221,17 @@ impl Scheduler for SchedulerCFS {
|
|||||||
|
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
// 如果当前不是running态,或者当前进程的虚拟运行时间大于等于下一个进程的,那就需要切换。
|
// 如果当前不是running态,或者当前进程的虚拟运行时间大于等于下一个进程的,那就需要切换。
|
||||||
if (ProcessManager::current_pcb().sched_info().state() != ProcessState::Runnable)
|
let state = ProcessManager::current_pcb()
|
||||||
|
.sched_info()
|
||||||
|
.inner_lock_read_irqsave()
|
||||||
|
.state();
|
||||||
|
if (state != ProcessState::Runnable)
|
||||||
|| (ProcessManager::current_pcb().sched_info().virtual_runtime()
|
|| (ProcessManager::current_pcb().sched_info().virtual_runtime()
|
||||||
>= proc.sched_info().virtual_runtime())
|
>= proc.sched_info().virtual_runtime())
|
||||||
{
|
{
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
// 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
// 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||||
if ProcessManager::current_pcb().sched_info().state() == ProcessState::Runnable {
|
if state == ProcessState::Runnable {
|
||||||
sched_enqueue(ProcessManager::current_pcb(), false);
|
sched_enqueue(ProcessManager::current_pcb(), false);
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,9 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
|
|||||||
// 当前进程持有锁,不切换,避免死锁
|
// 当前进程持有锁,不切换,避免死锁
|
||||||
if ProcessManager::current_pcb().preempt_count() != 0 {
|
if ProcessManager::current_pcb().preempt_count() != 0 {
|
||||||
let binding = ProcessManager::current_pcb();
|
let binding = ProcessManager::current_pcb();
|
||||||
let guard = binding.sched_info_try_upgradeable_irqsave(5);
|
let guard = binding
|
||||||
|
.sched_info()
|
||||||
|
.inner_lock_try_upgradable_read_irqsave(5);
|
||||||
if unlikely(guard.is_none()) {
|
if unlikely(guard.is_none()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -154,7 +156,7 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
|
|||||||
/// @param reset_time 是否重置虚拟运行时间
|
/// @param reset_time 是否重置虚拟运行时间
|
||||||
pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
|
pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
if pcb.sched_info().state() != ProcessState::Runnable {
|
if pcb.sched_info().inner_lock_read_irqsave().state() != ProcessState::Runnable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cfs_scheduler = __get_cfs_scheduler();
|
let cfs_scheduler = __get_cfs_scheduler();
|
||||||
@ -173,7 +175,7 @@ pub fn sched_enqueue(pcb: Arc<ProcessControlBlock>, mut reset_time: bool) {
|
|||||||
|
|
||||||
assert!(pcb.sched_info().on_cpu().is_some());
|
assert!(pcb.sched_info().on_cpu().is_some());
|
||||||
|
|
||||||
match pcb.sched_info().policy() {
|
match pcb.sched_info().inner_lock_read_irqsave().policy() {
|
||||||
SchedPolicy::CFS => {
|
SchedPolicy::CFS => {
|
||||||
if reset_time {
|
if reset_time {
|
||||||
cfs_scheduler.enqueue_reset_vruntime(pcb.clone());
|
cfs_scheduler.enqueue_reset_vruntime(pcb.clone());
|
||||||
@ -199,17 +201,19 @@ pub extern "C" fn sched_init() {
|
|||||||
|
|
||||||
/// @brief 当时钟中断到达时,更新时间片
|
/// @brief 当时钟中断到达时,更新时间片
|
||||||
/// 请注意,该函数只能被时钟中断处理程序调用
|
/// 请注意,该函数只能被时钟中断处理程序调用
|
||||||
pub extern "C" fn sched_update_jiffies() {
|
#[inline(never)]
|
||||||
|
pub fn sched_update_jiffies() {
|
||||||
let binding = ProcessManager::current_pcb();
|
let binding = ProcessManager::current_pcb();
|
||||||
let guard = binding.try_sched_info(10);
|
let guard = binding.sched_info().inner_lock_try_read_irqsave(10);
|
||||||
if unlikely(guard.is_none()) {
|
if unlikely(guard.is_none()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let guard = guard.unwrap();
|
let guard = guard.unwrap();
|
||||||
let policy = guard.policy();
|
let policy = guard.policy();
|
||||||
|
drop(guard);
|
||||||
match policy {
|
match policy {
|
||||||
SchedPolicy::CFS => {
|
SchedPolicy::CFS => {
|
||||||
__get_cfs_scheduler().timer_update_jiffies(&guard);
|
__get_cfs_scheduler().timer_update_jiffies(binding.sched_info());
|
||||||
}
|
}
|
||||||
SchedPolicy::FIFO | SchedPolicy::RR => {
|
SchedPolicy::FIFO | SchedPolicy::RR => {
|
||||||
__get_rt_scheduler().timer_update_jiffies();
|
__get_rt_scheduler().timer_update_jiffies();
|
||||||
|
@ -81,7 +81,7 @@ impl RTQueue {
|
|||||||
queue.push_front(pcb);
|
queue.push_front(pcb);
|
||||||
}
|
}
|
||||||
pub fn get_rt_queue_size(&mut self) -> usize {
|
pub fn get_rt_queue_size(&mut self) -> usize {
|
||||||
let queue = self.locked_queue.lock();
|
let queue = self.locked_queue.lock_irqsave();
|
||||||
return queue.len();
|
return queue.len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ impl Scheduler for SchedulerRT {
|
|||||||
let proc: Arc<ProcessControlBlock> =
|
let proc: Arc<ProcessControlBlock> =
|
||||||
self.pick_next_task_rt(cpu_id).expect("No RT process found");
|
self.pick_next_task_rt(cpu_id).expect("No RT process found");
|
||||||
let priority = proc.sched_info().priority();
|
let priority = proc.sched_info().priority();
|
||||||
let policy = proc.sched_info().policy();
|
let policy = proc.sched_info().inner_lock_read_irqsave().policy();
|
||||||
match policy {
|
match policy {
|
||||||
// 如果是fifo策略,则可以一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)
|
// 如果是fifo策略,则可以一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)
|
||||||
SchedPolicy::FIFO => {
|
SchedPolicy::FIFO => {
|
||||||
|
@ -100,7 +100,7 @@ impl Timekeeper {
|
|||||||
///
|
///
|
||||||
/// * 'clock' - 指定的时钟实际类型。初始为ClocksourceJiffies
|
/// * 'clock' - 指定的时钟实际类型。初始为ClocksourceJiffies
|
||||||
pub fn timekeeper_setup_internals(&self, clock: Arc<dyn Clocksource>) {
|
pub fn timekeeper_setup_internals(&self, clock: Arc<dyn Clocksource>) {
|
||||||
let mut timekeeper = self.0.write();
|
let mut timekeeper = self.0.write_irqsave();
|
||||||
// 更新clock
|
// 更新clock
|
||||||
let mut clock_data = clock.clocksource_data();
|
let mut clock_data = clock.clocksource_data();
|
||||||
clock_data.watchdog_last = clock.read();
|
clock_data.watchdog_last = clock.read();
|
||||||
@ -132,8 +132,9 @@ impl Timekeeper {
|
|||||||
/// # 获取当前时钟源距离上次检测走过的纳秒数
|
/// # 获取当前时钟源距离上次检测走过的纳秒数
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn tk_get_ns(&self) -> u64 {
|
pub fn tk_get_ns(&self) -> u64 {
|
||||||
let timekeeper = self.0.read();
|
let timekeeper = self.0.read_irqsave();
|
||||||
let clock = timekeeper.clock.clone().unwrap();
|
let clock = timekeeper.clock.clone().unwrap();
|
||||||
|
drop(timekeeper);
|
||||||
let clock_now = clock.read();
|
let clock_now = clock.read();
|
||||||
let clcok_data = clock.clocksource_data();
|
let clcok_data = clock.clocksource_data();
|
||||||
let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
|
let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
|
||||||
@ -164,7 +165,7 @@ pub fn getnstimeofday() -> TimeSpec {
|
|||||||
tv_sec: 0,
|
tv_sec: 0,
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
match timekeeper().0.try_read() {
|
match timekeeper().0.try_read_irqsave() {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some(tk) => {
|
Some(tk) => {
|
||||||
_xtime = tk.xtime;
|
_xtime = tk.xtime;
|
||||||
@ -215,7 +216,7 @@ pub fn timekeeping_init() {
|
|||||||
.expect("clocksource_default_clock enable failed");
|
.expect("clocksource_default_clock enable failed");
|
||||||
timekeeper().timekeeper_setup_internals(clock);
|
timekeeper().timekeeper_setup_internals(clock);
|
||||||
// 暂时不支持其他架构平台对时间的设置 所以使用x86平台对应值初始化
|
// 暂时不支持其他架构平台对时间的设置 所以使用x86平台对应值初始化
|
||||||
let mut timekeeper = timekeeper().0.write();
|
let mut timekeeper = timekeeper().0.write_irqsave();
|
||||||
timekeeper.xtime.tv_nsec = ktime_get_real_ns();
|
timekeeper.xtime.tv_nsec = ktime_get_real_ns();
|
||||||
|
|
||||||
// 初始化wall time到monotonic的时间
|
// 初始化wall time到monotonic的时间
|
||||||
@ -236,7 +237,7 @@ pub fn timekeeping_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// # 使用当前时钟源增加wall time
|
/// # 使用当前时钟源增加wall time
|
||||||
pub fn update_wall_time() {
|
pub fn update_wall_time(delta_us: i64) {
|
||||||
// kdebug!("enter update_wall_time, stack_use = {:}",stack_use);
|
// kdebug!("enter update_wall_time, stack_use = {:}",stack_use);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
@ -264,8 +265,7 @@ pub fn update_wall_time() {
|
|||||||
// ================
|
// ================
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
// !!! todo: 这里是硬编码了HPET的500us中断,需要修改
|
__ADDED_USEC.fetch_add(delta_us, Ordering::SeqCst);
|
||||||
__ADDED_USEC.fetch_add(500, Ordering::SeqCst);
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
let mut retry = 10;
|
let mut retry = 10;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
InterruptArch,
|
InterruptArch,
|
||||||
},
|
},
|
||||||
kerror, kinfo,
|
kerror, kinfo,
|
||||||
libs::spinlock::SpinLock,
|
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||||
process::{ProcessControlBlock, ProcessManager},
|
process::{ProcessControlBlock, ProcessManager},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,7 +57,9 @@ impl TimerFunction for WakeUpHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Timer(SpinLock<InnerTimer>);
|
pub struct Timer {
|
||||||
|
inner: SpinLock<InnerTimer>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Timer {
|
impl Timer {
|
||||||
/// @brief 创建一个定时器(单位:ms)
|
/// @brief 创建一个定时器(单位:ms)
|
||||||
@ -68,22 +70,28 @@ impl Timer {
|
|||||||
///
|
///
|
||||||
/// @return 定时器结构体
|
/// @return 定时器结构体
|
||||||
pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
|
pub fn new(timer_func: Box<dyn TimerFunction>, expire_jiffies: u64) -> Arc<Self> {
|
||||||
let result: Arc<Timer> = Arc::new(Timer(SpinLock::new(InnerTimer {
|
let result: Arc<Timer> = Arc::new(Timer {
|
||||||
expire_jiffies,
|
inner: SpinLock::new(InnerTimer {
|
||||||
timer_func,
|
expire_jiffies,
|
||||||
self_ref: Weak::default(),
|
timer_func: Some(timer_func),
|
||||||
triggered: false,
|
self_ref: Weak::default(),
|
||||||
})));
|
triggered: false,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
result.0.lock().self_ref = Arc::downgrade(&result);
|
result.inner.lock().self_ref = Arc::downgrade(&result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inner(&self) -> SpinLockGuard<InnerTimer> {
|
||||||
|
return self.inner.lock_irqsave();
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief 将定时器插入到定时器链表中
|
/// @brief 将定时器插入到定时器链表中
|
||||||
pub fn activate(&self) {
|
pub fn activate(&self) {
|
||||||
let inner_guard = self.0.lock();
|
let mut timer_list = TIMER_LIST.lock_irqsave();
|
||||||
let mut timer_list = TIMER_LIST.lock();
|
let inner_guard = self.inner();
|
||||||
|
|
||||||
// 链表为空,则直接插入
|
// 链表为空,则直接插入
|
||||||
if timer_list.is_empty() {
|
if timer_list.is_empty() {
|
||||||
@ -99,7 +107,7 @@ impl Timer {
|
|||||||
}
|
}
|
||||||
let mut split_pos: usize = 0;
|
let mut split_pos: usize = 0;
|
||||||
for (pos, elt) in timer_list.iter().enumerate() {
|
for (pos, elt) in timer_list.iter().enumerate() {
|
||||||
if elt.0.lock().expire_jiffies > inner_guard.expire_jiffies {
|
if elt.inner().expire_jiffies > inner_guard.expire_jiffies {
|
||||||
split_pos = pos;
|
split_pos = pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -113,9 +121,11 @@ impl Timer {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run(&self) {
|
fn run(&self) {
|
||||||
let mut timer = self.0.lock();
|
let mut timer = self.inner();
|
||||||
timer.triggered = true;
|
timer.triggered = true;
|
||||||
let r = timer.timer_func.run();
|
let func = timer.timer_func.take();
|
||||||
|
drop(timer);
|
||||||
|
let r = func.map(|mut f| f.run()).unwrap_or(Ok(()));
|
||||||
if unlikely(r.is_err()) {
|
if unlikely(r.is_err()) {
|
||||||
kerror!(
|
kerror!(
|
||||||
"Failed to run timer function: {self:?} {:?}",
|
"Failed to run timer function: {self:?} {:?}",
|
||||||
@ -126,14 +136,15 @@ impl Timer {
|
|||||||
|
|
||||||
/// ## 判断定时器是否已经触发
|
/// ## 判断定时器是否已经触发
|
||||||
pub fn timeout(&self) -> bool {
|
pub fn timeout(&self) -> bool {
|
||||||
self.0.lock().triggered
|
self.inner().triggered
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## 取消定时器任务
|
/// ## 取消定时器任务
|
||||||
pub fn cancel(&self) -> bool {
|
pub fn cancel(&self) -> bool {
|
||||||
|
let this_arc = self.inner().self_ref.upgrade().unwrap();
|
||||||
TIMER_LIST
|
TIMER_LIST
|
||||||
.lock()
|
.lock_irqsave()
|
||||||
.extract_if(|x| Arc::<Timer>::as_ptr(&x) == self as *const Timer)
|
.extract_if(|x| Arc::ptr_eq(&this_arc, x))
|
||||||
.for_each(|p| drop(p));
|
.for_each(|p| drop(p));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -145,7 +156,7 @@ pub struct InnerTimer {
|
|||||||
/// 定时器结束时刻
|
/// 定时器结束时刻
|
||||||
pub expire_jiffies: u64,
|
pub expire_jiffies: u64,
|
||||||
/// 定时器需要执行的函数结构体
|
/// 定时器需要执行的函数结构体
|
||||||
pub timer_func: Box<dyn TimerFunction>,
|
pub timer_func: Option<Box<dyn TimerFunction>>,
|
||||||
/// self_ref
|
/// self_ref
|
||||||
self_ref: Weak<Timer>,
|
self_ref: Weak<Timer>,
|
||||||
/// 判断该计时器是否触发
|
/// 判断该计时器是否触发
|
||||||
@ -187,7 +198,7 @@ impl SoftirqVec for DoTimerSoftirq {
|
|||||||
// 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
|
// 最多只处理TIMER_RUN_CYCLE_THRESHOLD个计时器
|
||||||
for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
|
for _ in 0..TIMER_RUN_CYCLE_THRESHOLD {
|
||||||
// kdebug!("DoTimerSoftirq run");
|
// kdebug!("DoTimerSoftirq run");
|
||||||
let timer_list = TIMER_LIST.try_lock();
|
let timer_list = TIMER_LIST.try_lock_irqsave();
|
||||||
if timer_list.is_err() {
|
if timer_list.is_err() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -201,7 +212,7 @@ impl SoftirqVec for DoTimerSoftirq {
|
|||||||
// kdebug!("to lock timer_list_front");
|
// kdebug!("to lock timer_list_front");
|
||||||
let mut timer_list_front_guard = None;
|
let mut timer_list_front_guard = None;
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let x = timer_list_front.0.try_lock();
|
let x = timer_list_front.inner.try_lock_irqsave();
|
||||||
if x.is_err() {
|
if x.is_err() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -297,7 +308,7 @@ pub fn timer_get_first_expire() -> Result<u64, SystemError> {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
} else {
|
} else {
|
||||||
// kdebug!("timer_list not empty");
|
// kdebug!("timer_list not empty");
|
||||||
return Ok(timer_list.front().unwrap().0.lock().expire_jiffies);
|
return Ok(timer_list.front().unwrap().inner().expire_jiffies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 加锁失败返回啥??
|
// 加锁失败返回啥??
|
||||||
@ -310,10 +321,10 @@ pub fn timer_get_first_expire() -> Result<u64, SystemError> {
|
|||||||
/// 更新系统时间片
|
/// 更新系统时间片
|
||||||
///
|
///
|
||||||
/// todo: 这里的实现有问题,貌似把HPET的500us当成了500个jiffies,然后update_wall_time()里面也硬编码了这个500us
|
/// todo: 这里的实现有问题,貌似把HPET的500us当成了500个jiffies,然后update_wall_time()里面也硬编码了这个500us
|
||||||
pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
|
pub fn update_timer_jiffies(add_jiffies: u64, time_us: i64) -> u64 {
|
||||||
let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
|
let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
update_wall_time();
|
update_wall_time(time_us);
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
return prev + add_jiffies;
|
return prev + add_jiffies;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user