Add early_exit2 & Fix issue #60.

ch8
Yifan Wu 3 years ago
parent 5729debb09
commit fcfd5b6db7

@ -21,6 +21,14 @@ impl TaskManager {
pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
self.ready_queue.pop_front()
}
pub fn remove(&mut self, task: Arc<TaskControlBlock>) {
if let Some((id, _)) = self.ready_queue
.iter()
.enumerate()
.find(|(_, t)| Arc::as_ptr(t) == Arc::as_ptr(&task)) {
self.ready_queue.remove(id);
}
}
}
lazy_static! {
@ -34,6 +42,10 @@ pub fn add_task(task: Arc<TaskControlBlock>) {
TASK_MANAGER.exclusive_access().add(task);
}
pub fn remove_task(task: Arc<TaskControlBlock>) {
TASK_MANAGER.exclusive_access().remove(task);
}
pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
TASK_MANAGER.exclusive_access().fetch()
}

@ -15,10 +15,11 @@ use lazy_static::*;
use manager::fetch_task;
use process::ProcessControlBlock;
use switch::__switch;
use crate::timer::remove_timer;
pub use context::TaskContext;
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle};
pub use manager::{add_task, pid2process, remove_from_pid2process};
pub use manager::{add_task, remove_task, pid2process, remove_from_pid2process};
pub use processor::{
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
current_user_token, run_tasks, schedule, take_current_task,
@ -90,6 +91,9 @@ pub fn exit_current_and_run_next(exit_code: i32) {
let mut recycle_res = Vec::<TaskUserRes>::new();
for task in process_inner.tasks.iter().filter(|t| t.is_some()) {
let task = task.as_ref().unwrap();
// if other tasks are Ready in TaskManager or waiting for a timer to be
// expired, we should remove them.
remove_inactive_task(Arc::clone(&task));
let mut task_inner = task.inner_exclusive_access();
if let Some(res) = task_inner.res.take() {
recycle_res.push(res);
@ -107,6 +111,8 @@ pub fn exit_current_and_run_next(exit_code: i32) {
process_inner.memory_set.recycle_data_pages();
// drop file descriptors
process_inner.fd_table.clear();
// remove all tasks
process_inner.tasks.clear();
}
drop(process);
// we do not have to save task context
@ -137,3 +143,8 @@ pub fn current_add_signal(signal: SignalFlags) {
let mut process_inner = process.inner_exclusive_access();
process_inner.signals |= signal;
}
pub fn remove_inactive_task(task: Arc<TaskControlBlock>) {
remove_task(Arc::clone(&task));
remove_timer(Arc::clone(&task));
}

@ -59,6 +59,18 @@ pub fn add_timer(expire_ms: usize, task: Arc<TaskControlBlock>) {
timers.push(TimerCondVar { expire_ms, task });
}
pub fn remove_timer(task: Arc<TaskControlBlock>) {
let mut timers = TIMERS.exclusive_access();
let mut temp = BinaryHeap::<TimerCondVar>::new();
for condvar in timers.drain() {
if Arc::as_ptr(&task) != Arc::as_ptr(&condvar.task) {
temp.push(condvar);
}
}
timers.clear();
timers.append(&mut temp);
}
pub fn check_timer() {
let current_ms = get_time_ms();
let mut timers = TIMERS.exclusive_access();

@ -5,7 +5,6 @@
extern crate user_lib;
extern crate alloc;
use alloc::vec::Vec;
use user_lib::{exit, thread_create};
pub fn thread_a() -> ! {

@ -0,0 +1,24 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use user_lib::{exit, thread_create, sleep};
pub fn thread_a() -> ! {
println!("into thread_a");
sleep(1000);
// the following message cannot be seen since the main thread has exited before
println!("exit thread_a");
exit(1)
}
#[no_mangle]
pub fn main() -> i32 {
thread_create(thread_a as usize, 0);
sleep(100);
println!("main thread exited.");
exit(0)
}
Loading…
Cancel
Save