kernel/sched/
dispatcher.rs1use 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}