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) {
20        // crate::println!("Dispatcher: Dispatching task {} (state: {:?})", task.get_id(), task.state);
21        
22        // The current task's state has already been saved by the scheduler
23        // We just need to load the next task's state
24
25        match task.state {
26            TaskState::NotInitialized => {
27                match task.task_type {
28                    TaskType::Kernel => {
29                        panic!("Kernel task should not be in NotInitialized state");
30                    }
31                    TaskType::User => {
32                        panic!("User task should not be in NotInitialized state");
33                    }
34                }
35            }
36            TaskState::Ready => {
37                task.state = TaskState::Running;
38                set_trapvector(get_trampoline_trap_vector());
39                let trapframe = cpu.get_trapframe();
40                trapframe.set_trap_handler(get_user_trap_handler());
41                trapframe.set_next_address_space(task.vm_manager.get_asid());
42                task.vcpu.set_pc(task.entry as u64);
43                task.vcpu.switch(cpu);
44                set_next_mode(task.vcpu.get_mode());
45            }
46            TaskState::Running => {
47                set_trapvector(get_trampoline_trap_vector());
48                let trapframe = cpu.get_trapframe();
49                trapframe.set_trap_handler(get_user_trap_handler());
50                trapframe.set_next_address_space(task.vm_manager.get_asid());
51                task.vcpu.switch(cpu);
52                set_next_mode(task.vcpu.get_mode());
53            }
54            TaskState::Zombie => {
55            },
56            TaskState::Terminated => {
57            }
58            _ => {}
59        }
60    }
61}