DragonOS/kernel/src/process/process.rs
houmkh f6ba114bb0
Block IO Scheduler (#158)
* Block io调度器
* process_wakeup时,对cfs的进程,重设虚拟运行时间。解决由于休眠的进程,其虚拟运行时间过小,导致其他进程饥饿的问题

* 1、为AP核启动apic_timer,使其能够运行调度
2、增加kick_cpu功能,支持让某个特定核心立即运行调度器
3、wait_queue的唤醒,改为立即唤醒。
4、增加进程在核心间迁移的功能
5、CFS调度器为每个核心设置单独的IDLE进程pcb(pid均为0)
6、pcb中增加migrate_to字段
7、当具有多核时,io调度器在核心1上运行。

* io调度器文件位置修改

* 修改io的makefile

* 更新makefile中的变量名

* 修改io调度器函数名

---------

Co-authored-by: login <longjin@ringotek.cn>
2023-02-04 12:31:15 +08:00

102 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use core::ptr::{read_volatile, write_volatile};
use crate::{
arch::asm::current::current_pcb,
include::bindings::bindings::{process_control_block, PROC_RUNNING, PROC_STOPPED},
sched::core::{cpu_executing, sched_enqueue},
smp::core::{smp_get_processor_id, smp_send_reschedule},
};
use super::preempt::{preempt_disable, preempt_enable};
/// 判断进程是否已经停止
#[no_mangle]
pub extern "C" fn process_is_stopped(pcb: *const process_control_block) -> bool {
let state: u64 = unsafe { read_volatile(&(*pcb).state) } as u64;
if (state & (PROC_STOPPED as u64)) != 0 {
return true;
} else {
return false;
}
}
/// @brief 尝试唤醒指定的进程。
/// 本函数的行为If (@_state & @pcb->state) @pcb->state = TASK_RUNNING.
///
/// @param _pcb 要被唤醒的进程的pcb
/// @param _state 如果pcb的state与_state匹配则唤醒这个进程
/// @param _wake_flags 保留暂未使用请置为0
/// @return true: 成功唤醒
/// false: 不符合唤醒条件,无法唤醒
#[no_mangle]
pub extern "C" fn process_try_to_wake_up(
_pcb: *mut process_control_block,
_state: u64,
_wake_flags: i32,
) -> bool {
preempt_disable();
let mut retval = false;
// 获取对pcb的可变引用
let pcb = unsafe { _pcb.as_mut() }.unwrap();
// 如果要唤醒的就是当前的进程
if current_pcb() as *mut process_control_block as usize == _pcb as usize {
unsafe {
write_volatile(&mut pcb.state, PROC_RUNNING as u64);
}
preempt_enable();
retval = true;
return retval;
}
// todo: 将来调度器引入ttwu队列之后需要修改这里的判断条件
// todo: 为pcb引入pi_lock,然后在这里加锁
if unsafe { read_volatile(&pcb.state) } & _state != 0 {
// 可以wakeup
unsafe {
write_volatile(&mut pcb.state, PROC_RUNNING as u64);
}
sched_enqueue(pcb, true);
retval = true;
}
// todo: 对pcb的pi_lock放锁
preempt_enable();
return retval;
}
/// @brief 当进程,满足 (@state & @pcb->state)时,唤醒进程,并设置: @pcb->state = TASK_RUNNING.
///
/// @return true 唤醒成功
/// @return false 唤醒失败
#[no_mangle]
pub extern "C" fn process_wake_up_state(pcb: *mut process_control_block, state: u64) -> bool {
return process_try_to_wake_up(pcb, state, 0);
}
/// @brief 让一个正在cpu上运行的进程陷入内核
pub fn process_kick(pcb: *mut process_control_block) {
preempt_disable();
let cpu = process_cpu(pcb);
// 如果给定的进程正在别的核心上执行,则立即发送请求,让它陷入内核态,以及时响应信号。
if cpu != smp_get_processor_id() && process_is_executing(pcb) {
smp_send_reschedule(cpu);
}
preempt_enable();
}
/// @brief 获取给定的进程在哪个cpu核心上运行(使用volatile避免编译器优化)
#[inline]
pub fn process_cpu(pcb: *const process_control_block) -> u32 {
unsafe { read_volatile(&(*pcb).cpu_id) }
}
/// @brief 判断给定的进程是否正在处理器上执行
///
/// @param pcb 进程的pcb
#[inline]
pub fn process_is_executing(pcb: *const process_control_block) -> bool {
return cpu_executing(process_cpu(pcb)) as *const process_control_block == pcb;
}