kernel/sched/
dispatcher.rs

1//! Dispatcher module.
2//! 
3//! The dispatcher module is responsible for dispatching tasks to the CPU.
4//! Currently, the dispatcher is a simple dispatcher that runs the task.
5
6use crate::arch::{get_user_trap_handler, set_next_mode, set_trapvector, Arch};
7
8use crate::task::{Task, TaskState, TaskType};
9use crate::vm::get_trampoline_trap_vector;
10
11pub struct Dispatcher;
12
13impl Dispatcher {
14    pub const fn new() -> Self {
15        Dispatcher {}
16    }
17
18    #[allow(static_mut_refs)]
19    pub fn dispatch(&mut self, cpu: &mut Arch, task: &mut Task, prev_task: Option<&mut Task>) {
20        if let Some(prev_task) = prev_task {
21            prev_task.vcpu.store(cpu);
22        }
23
24        match task.state {
25            TaskState::NotInitialized => {
26                match task.task_type {
27                    TaskType::Kernel => {
28                        panic!("Kernel task should not be in NotInitialized state");
29                    }
30                    TaskType::User => {
31                        panic!("User task should not be in NotInitialized state");
32                    }
33                }
34            }
35            TaskState::Ready => {
36                task.state = TaskState::Running;
37                set_trapvector(get_trampoline_trap_vector());
38                let trapframe = cpu.get_trapframe();
39                trapframe.set_trap_handler(get_user_trap_handler());
40                trapframe.set_next_address_space(task.vm_manager.get_asid());
41                task.vcpu.set_pc(task.entry as u64);
42                task.vcpu.switch(cpu);
43                set_next_mode(task.vcpu.get_mode());
44            }
45            TaskState::Running => {
46                set_trapvector(get_trampoline_trap_vector());
47                let trapframe = cpu.get_trapframe();
48                trapframe.set_trap_handler(get_user_trap_handler());
49                trapframe.set_next_address_space(task.vm_manager.get_asid());
50                task.vcpu.switch(cpu);
51                set_next_mode(task.vcpu.get_mode());
52            }
53            TaskState::Zombie => {
54            },
55            TaskState::Terminated => {
56            }
57            _ => {}
58        }
59    }
60}