sparreal_kernel/task/
schedule.rs1use alloc::collections::vec_deque::VecDeque;
2use log::debug;
3use spin::Mutex;
4
5use crate::platform_if::PlatformImpl;
6
7use super::tcb::{TaskControlBlock, TaskState, current};
8
9static IDLE: Mutex<VecDeque<TaskControlBlock>> = Mutex::new(VecDeque::new());
10static FINISHED: Mutex<VecDeque<TaskControlBlock>> = Mutex::new(VecDeque::new());
11
12pub fn schedule() {
13 let idle = idle_pop();
14 if let Some(mut idle) = idle {
15 let mut cu = current();
16 if matches!(cu.state, TaskState::Running) {
17 cu.state = TaskState::Suspend;
18 }
19 idle.state = TaskState::Running;
20
21 cu.switch_to(&idle);
22 } else {
23 debug!("No task idle");
24 loop {
25 PlatformImpl::wait_for_interrupt();
26 }
27 }
28}
29
30pub fn idle_push(tcb: TaskControlBlock) {
31 IDLE.lock().push_back(tcb);
32}
33
34pub fn idle_pop() -> Option<TaskControlBlock> {
35 let mut g = IDLE.lock();
36 while let Some(one) = g.pop_front() {
37 if matches!(one.state, TaskState::Stopped) {
38 unsafe { one.drop() };
39 continue;
40 }
41 return Some(one);
42 }
43 None
44}
45
46pub fn finished_push(tcb: TaskControlBlock) {
47 FINISHED.lock().push_back(tcb);
48}
49
50pub fn suspend() {
51 let mut current = current();
52 current.state = TaskState::Suspend;
53 schedule();
54}