starry_api/imp/task/
exit.rs1use axprocess::Pid;
2use axsignal::{SignalInfo, Signo};
3use axtask::{TaskExtRef, current};
4use linux_raw_sys::general::SI_KERNEL;
5use starry_core::task::ProcessData;
6
7use crate::{
8 file::FD_TABLE,
9 ptr::UserPtr,
10 signal::{send_signal_process, send_signal_thread},
11};
12
13pub fn do_exit(exit_code: i32, group_exit: bool) -> ! {
14 let curr = current();
15 let curr_ext = curr.task_ext();
16
17 let thread = &curr_ext.thread;
18 info!("{:?} exit with code: {}", thread, exit_code);
19
20 let clear_child_tid = UserPtr::<Pid>::from(curr_ext.thread_data().clear_child_tid());
21 if let Ok(clear_tid) = clear_child_tid.get_as_mut() {
22 *clear_tid = 0;
23
24 let guard = curr_ext
25 .process_data()
26 .futex_table
27 .get(clear_tid as *const _ as usize);
28 if let Some(futex) = guard {
29 futex.notify_one(false);
30 }
31 axtask::yield_now();
32 }
33
34 let process = thread.process();
35 if thread.exit(exit_code) {
36 process.exit();
37 if let Some(parent) = process.parent() {
38 if let Some(signo) = process.data::<ProcessData>().and_then(|it| it.exit_signal) {
39 let _ = send_signal_process(&parent, SignalInfo::new(signo, SI_KERNEL as _));
40 }
41 if let Some(data) = parent.data::<ProcessData>() {
42 data.child_exit_wq.notify_all(false)
43 }
44 }
45
46 process.exit();
47 FD_TABLE.clear();
50 }
51 if group_exit && !process.is_group_exited() {
52 process.group_exit();
53 let sig = SignalInfo::new(Signo::SIGKILL, SI_KERNEL as _);
54 for thr in process.threads() {
55 let _ = send_signal_thread(&thr, sig.clone());
56 }
57 }
58 axtask::exit(exit_code)
59}
60
61pub fn sys_exit(exit_code: i32) -> ! {
62 do_exit(exit_code << 8, false)
63}
64
65pub fn sys_exit_group(exit_code: i32) -> ! {
66 do_exit(exit_code << 8, true)
67}