1mod context;
18mod manager;
19mod pid;
20mod processor;
21mod switch;
22#[allow(clippy::module_inception)]
23mod task;
24
25use crate::loader::get_app_data_by_name;
26use crate::sbi::shutdown;
27use alloc::sync::Arc;
28use lazy_static::*;
29pub use manager::{TaskManager, fetch_task};
30use switch::__switch;
31use task::{TaskControlBlock, TaskStatus};
32
33pub use context::TaskContext;
34pub use manager::add_task;
35pub use pid::{KernelStack, PidAllocator, PidHandle, pid_alloc};
36pub use processor::{
37 Processor, current_task, current_trap_cx, current_user_token, run_tasks, schedule,
38 take_current_task,
39};
40pub fn suspend_current_and_run_next() {
42 let task = take_current_task().unwrap();
44
45 let mut task_inner = task.inner_exclusive_access();
47 let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
48 task_inner.task_status = TaskStatus::Ready;
50 drop(task_inner);
51 add_task(task);
55 schedule(task_cx_ptr);
57}
58
59pub const IDLE_PID: usize = 0;
61
62pub fn exit_current_and_run_next(exit_code: i32) {
64 let task = take_current_task().unwrap();
66
67 let pid = task.getpid();
68 if pid == IDLE_PID {
69 println!(
70 "[kernel] Idle process exit with exit_code {} ...",
71 exit_code
72 );
73 if exit_code != 0 {
74 shutdown(true)
76 } else {
77 shutdown(false)
79 }
80 }
81
82 let mut inner = task.inner_exclusive_access();
84 inner.task_status = TaskStatus::Zombie;
86 inner.exit_code = exit_code;
88 {
92 let mut initproc_inner = INITPROC.inner_exclusive_access();
93 for child in inner.children.iter() {
94 child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
95 initproc_inner.children.push(child.clone());
96 }
97 }
98 inner.children.clear();
101 inner.memory_set.recycle_data_pages();
103 drop(inner);
104 drop(task);
107 let mut _unused = TaskContext::zero_init();
109 schedule(&mut _unused as *mut _);
110}
111
112lazy_static! {
113 pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new(TaskControlBlock::new(
115 get_app_data_by_name("initproc").unwrap()
116 ));
117}
118pub fn add_initproc() {
120 add_task(INITPROC.clone());
121}