repair some bugs

master
chenqiuhao 6 years ago
parent 8d6d3b7c37
commit 6652f8daf6

@ -4,6 +4,7 @@
#![feature(linkage)] #![feature(linkage)]
#![feature(nll)] #![feature(nll)]
#![feature(vec_resize_default)] #![feature(vec_resize_default)]
#![feature(exact_size_is_empty)]
extern crate alloc; extern crate alloc;
#[macro_use] #[macro_use]

@ -56,9 +56,17 @@ impl ProcessManager {
fn alloc_pid(&self) -> Pid { fn alloc_pid(&self) -> Pid {
for (i, proc) in self.procs.iter().enumerate() { for (i, proc) in self.procs.iter().enumerate() {
if proc.lock().is_none() { let mut proc_lock = proc.lock();
if proc_lock.is_none() {
return i; return i;
} }
match proc_lock.as_mut().unwrap().status {
Status::Exited(_) => if self.wait_queue[i].lock().is_empty() {
*proc_lock = None;
return i;
},
_ => {},
}
} }
panic!("Process number exceeded"); panic!("Process number exceeded");
} }
@ -130,7 +138,7 @@ impl ProcessManager {
fn set_status(&self, pid: Pid, status: Status) { fn set_status(&self, pid: Pid, status: Status) {
let mut proc_lock = self.procs[pid].lock(); let mut proc_lock = self.procs[pid].lock();
let mut proc = proc_lock.as_mut().expect("process not exist"); let mut proc = proc_lock.as_mut().expect("process not exist");
trace!("process {} {:?} -> {:?}", pid, proc.status, status); //info!("process {} {:?} -> {:?}", pid, proc.status, status);
{ // limit the lifetime of scheduler { // limit the lifetime of scheduler
let mut scheduler = self.scheduler.lock(); let mut scheduler = self.scheduler.lock();
match (&proc.status, &status) { match (&proc.status, &status) {
@ -157,14 +165,25 @@ impl ProcessManager {
pub fn get_status(&self, pid: Pid) -> Option<Status> { pub fn get_status(&self, pid: Pid) -> Option<Status> {
self.procs[pid].lock().as_ref().map(|p| p.status.clone()) let mut proc_lock = self.procs[pid].lock();
if proc_lock.is_none() {
return None;
}
match proc_lock.as_ref().unwrap().status {
Status::Exited(_) => if self.wait_queue[pid].lock().is_empty() {
*proc_lock = None;
return None;
},
_ => {},
}
proc_lock.as_ref().map(|p| p.status.clone())
} }
pub fn remove(&self, pid: Pid) { pub fn wait_done(&self, pid: Pid, target: Pid) {
let mut proc_lock = self.procs[pid].lock(); let mut proc_lock = self.procs[target].lock();
let proc = proc_lock.as_ref().expect("process not exist"); let proc = proc_lock.as_ref().expect("process not exist");
match proc.status { match proc.status {
Status::Exited(_) => *proc_lock = None, Status::Exited(_) => self.wait_queue[target].lock().retain(|&i| i != pid),
_ => panic!("can not remove non-exited process"), _ => panic!("can not remove non-exited process"),
} }
} }
@ -185,17 +204,28 @@ impl ProcessManager {
self.set_status(pid, Status::Waiting(target)); self.set_status(pid, Status::Waiting(target));
self.wait_queue[target].lock().push(pid); self.wait_queue[target].lock().push(pid);
} }
pub fn wait_child(&self, pid: Pid) {
self.set_status(pid, Status::Waiting(0));
}
pub fn set_parent(&self, pid: Pid, target: Pid) {
self.wait_queue[target].lock().push(pid);
}
pub fn del_parent(&self, pid: Pid, target: Pid) {
self.wait_queue[target].lock().retain(|&i| i != pid);
}
pub fn exit(&self, pid: Pid, code: ExitCode) { pub fn exit(&self, pid: Pid, code: ExitCode) {
(self.exit_handler)(pid);
self.set_status(pid, Status::Exited(code)); self.set_status(pid, Status::Exited(code));
} }
/// Called when a process exit /// Called when a process exit
fn exit_handler(&self, pid: Pid, proc: &mut Process) { fn exit_handler(&self, pid: Pid, proc: &mut Process) {
for waiter in self.wait_queue[pid].lock().drain(..) { for waiter in self.wait_queue[pid].lock().iter() {
self.wakeup(waiter); self.wakeup(*waiter);
} }
proc.context = None;
(self.exit_handler)(pid); //proc.context = None;
} }
} }
fn new_vec_default<T: Default>(size: usize) -> Vec<T> { fn new_vec_default<T: Default>(size: usize) -> Vec<T> {

@ -151,7 +151,7 @@ impl<T> JoinHandle<T> {
loop { loop {
match processor().manager().get_status(self.thread.pid) { match processor().manager().get_status(self.thread.pid) {
Some(Status::Exited(exit_code)) => { Some(Status::Exited(exit_code)) => {
processor().manager().remove(self.thread.pid); processor().manager().wait_done(current().id(), self.thread.pid);
// Find return value on the heap from the exit code. // Find return value on the heap from the exit code.
return Ok(unsafe { *Box::from_raw(exit_code as *mut T) }); return Ok(unsafe { *Box::from_raw(exit_code as *mut T) });
} }

@ -63,9 +63,11 @@ pub fn shell() {
//memory_set_map_swappable(processor().get_context_mut(pid).get_memory_set_mut()); //memory_set_map_swappable(processor().get_context_mut(pid).get_memory_set_mut());
processor().manager().wait(thread::current().id(), pid); processor().manager().wait(thread::current().id(), pid);
processor().yield_now(); processor().yield_now();
processor().manager().wait_done(thread::current().id(), pid);
} else { } else {
println!("Program not exist"); println!("Program not exist");
} }
//break;
} }
unsafe { dealloc(buf.as_mut_ptr(), layout) }; unsafe { dealloc(buf.as_mut_ptr(), layout) };
} }

@ -36,21 +36,19 @@ static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(
pub struct Process { pub struct Process {
parent: AtomicUsize, parent: AtomicUsize,
children: Mutex<Vec<usize>>, children: Mutex<Vec<usize>>,
subproc_exit: Condvar, // Trigger parent's when exit
} }
impl Process { impl Process {
pub fn new_fork(pid: usize, parent: usize) { pub fn new_fork(pid: usize, parent: usize) {
PROCESS[pid].parent.store(parent, Ordering::Relaxed); PROCESS[pid].parent.store(parent, Ordering::Relaxed);
PROCESS[pid].subproc_exit._clear();
PROCESS[parent].children.lock().push(pid); PROCESS[parent].children.lock().push(pid);
} }
pub fn proc_exit(pid: usize) { pub fn proc_exit(pid: usize) {
let parent = PROCESS[pid].parent.load(Ordering::Relaxed); info!("proc_exit");
PROCESS[parent].subproc_exit.notify_all(); for child in PROCESS[pid].children.lock().clone() {
info!("del child {}", child);
processor().manager().del_parent(pid, child);
} }
pub fn wait_child() {
Self::current().subproc_exit._wait();
} }
pub fn get_children() -> Vec<usize> { pub fn get_children() -> Vec<usize> {
Self::current().children.lock().clone() Self::current().children.lock().clone()

@ -65,6 +65,7 @@ fn sys_fork(tf: &TrapFrame) -> i32 {
let mut context = process().fork(tf); let mut context = process().fork(tf);
//memory_set_map_swappable(context.get_memory_set_mut()); //memory_set_map_swappable(context.get_memory_set_mut());
let pid = processor().manager().add(context); let pid = processor().manager().add(context);
processor().manager().set_parent(thread::current().id(), pid);
Process::new_fork(pid, thread::current().id()); Process::new_fork(pid, thread::current().id());
//memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut()); //memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut());
info!("fork: {} -> {}", thread::current().id(), pid); info!("fork: {} -> {}", thread::current().id(), pid);
@ -88,7 +89,7 @@ fn sys_wait(pid: usize, code: *mut i32) -> i32 {
if !code.is_null() { if !code.is_null() {
unsafe { code.write(exit_code as i32); } unsafe { code.write(exit_code as i32); }
} }
processor().manager().remove(pid); processor().manager().wait_done(thread::current().id(), pid);
Process::do_wait(pid); Process::do_wait(pid);
info!("wait: {} -> {}", thread::current().id(), pid); info!("wait: {} -> {}", thread::current().id(), pid);
return 0; return 0;
@ -98,7 +99,8 @@ fn sys_wait(pid: usize, code: *mut i32) -> i32 {
} }
} }
if pid == 0 { if pid == 0 {
Process::wait_child(); processor().manager().wait_child(thread::current().id());
processor().yield_now();
} else { } else {
processor().manager().wait(thread::current().id(), pid); processor().manager().wait(thread::current().id(), pid);
processor().yield_now(); processor().yield_now();

Loading…
Cancel
Save