1 use core::ptr::{read_volatile, write_volatile};
2 
3 use crate::{
4     arch::asm::current::current_pcb,
5     include::bindings::bindings::{
6         process_control_block, PROC_RUNNING, PROC_STOPPED,
7     },
8     sched::core::{cpu_executing, sched_enqueue},
9     smp::core::{smp_get_processor_id, smp_send_reschedule},
10 };
11 
12 use super::preempt::{preempt_disable, preempt_enable};
13 
14 /// 判断进程是否已经停止
15 #[no_mangle]
process_is_stopped(pcb: *const process_control_block) -> bool16 pub extern "C" fn process_is_stopped(pcb: *const process_control_block) -> bool {
17     let state: u64 = unsafe { read_volatile(&(*pcb).state) } as u64;
18     if (state & (PROC_STOPPED as u64)) != 0 {
19         return true;
20     } else {
21         return false;
22     }
23 }
24 
25 /// @brief 尝试唤醒指定的进程。
26 /// 本函数的行为:If (@_state & @pcb->state) @pcb->state = TASK_RUNNING.
27 ///
28 /// @param _pcb 要被唤醒的进程的pcb
29 /// @param _state 如果pcb的state与_state匹配,则唤醒这个进程
30 /// @param _wake_flags 保留,暂未使用,请置为0
31 /// @return true: 成功唤醒
32 ///         false: 不符合唤醒条件,无法唤醒
33 #[no_mangle]
process_try_to_wake_up( _pcb: *mut process_control_block, _state: u64, _wake_flags: i32, ) -> bool34 pub extern "C" fn process_try_to_wake_up(
35     _pcb: *mut process_control_block,
36     _state: u64,
37     _wake_flags: i32,
38 ) -> bool {
39     preempt_disable();
40 
41     let mut retval = false;
42     // 获取对pcb的可变引用
43     let pcb = unsafe { _pcb.as_mut() }.unwrap();
44 
45     // 如果要唤醒的就是当前的进程
46     if current_pcb() as *mut process_control_block as usize == _pcb as usize {
47         unsafe {
48             write_volatile(&mut pcb.state, PROC_RUNNING as u64);
49         }
50         preempt_enable();
51         retval = true;
52         return retval;
53     }
54     // todo: 将来调度器引入ttwu队列之后,需要修改这里的判断条件
55 
56     // todo: 为pcb引入pi_lock,然后在这里加锁
57     if unsafe { read_volatile(&pcb.state) } & _state != 0 {
58         // 可以wakeup
59         unsafe {
60             write_volatile(&mut pcb.state, PROC_RUNNING as u64);
61             sched_enqueue(pcb);
62         }
63         retval = true;
64     }
65     // todo: 对pcb的pi_lock放锁
66     preempt_enable();
67     return retval;
68 }
69 
70 /// @brief 当进程,满足 (@state & @pcb->state)时,唤醒进程,并设置: @pcb->state = TASK_RUNNING.
71 ///
72 /// @return true 唤醒成功
73 /// @return false 唤醒失败
74 #[no_mangle]
process_wake_up_state(pcb: *mut process_control_block, state: u64) -> bool75 pub extern "C" fn process_wake_up_state(pcb: *mut process_control_block, state: u64) -> bool {
76     return process_try_to_wake_up(pcb, state, 0);
77 }
78 
79 /// @brief 让一个正在cpu上运行的进程陷入内核
process_kick(pcb: *mut process_control_block)80 pub fn process_kick(pcb: *mut process_control_block) {
81     preempt_disable();
82     let cpu = process_cpu(pcb);
83     // 如果给定的进程正在别的核心上执行,则立即发送请求,让它陷入内核态,以及时响应信号。
84     if cpu != smp_get_processor_id() && process_is_executing(pcb) {
85         smp_send_reschedule(cpu);
86     }
87     preempt_enable();
88 }
89 
90 /// @brief 获取给定的进程在哪个cpu核心上运行(使用volatile避免编译器优化)
91 #[inline]
process_cpu(pcb: *const process_control_block) -> u3292 pub fn process_cpu(pcb: *const process_control_block) -> u32 {
93     unsafe { read_volatile(&(*pcb).cpu_id) }
94 }
95 
96 /// @brief 判断给定的进程是否正在处理器上执行
97 ///
98 /// @param pcb 进程的pcb
99 #[inline]
process_is_executing(pcb: *const process_control_block) -> bool100 pub fn process_is_executing(pcb: *const process_control_block) -> bool {
101     return cpu_executing(process_cpu(pcb)) as *const process_control_block == pcb;
102 }
103