repair some bugs

master
chenqiuhao 6 years ago
parent 8d6d3b7c37
commit 6652f8daf6

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

@ -56,9 +56,17 @@ impl ProcessManager {
fn alloc_pid(&self) -> Pid {
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;
}
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");
}
@ -130,7 +138,7 @@ impl ProcessManager {
fn set_status(&self, pid: Pid, status: Status) {
let mut proc_lock = self.procs[pid].lock();
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
let mut scheduler = self.scheduler.lock();
match (&proc.status, &status) {
@ -157,14 +165,25 @@ impl ProcessManager {
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) {
let mut proc_lock = self.procs[pid].lock();
pub fn wait_done(&self, pid: Pid, target: Pid) {
let mut proc_lock = self.procs[target].lock();
let proc = proc_lock.as_ref().expect("process not exist");
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"),
}
}
@ -185,17 +204,28 @@ impl ProcessManager {
self.set_status(pid, Status::Waiting(target));
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) {
(self.exit_handler)(pid);
self.set_status(pid, Status::Exited(code));
}
/// Called when a process exit
fn exit_handler(&self, pid: Pid, proc: &mut Process) {
for waiter in self.wait_queue[pid].lock().drain(..) {
self.wakeup(waiter);
for waiter in self.wait_queue[pid].lock().iter() {
self.wakeup(*waiter);
}
proc.context = None;
(self.exit_handler)(pid);
//proc.context = None;
}
}
fn new_vec_default<T: Default>(size: usize) -> Vec<T> {

@ -151,7 +151,7 @@ impl<T> JoinHandle<T> {
loop {
match processor().manager().get_status(self.thread.pid) {
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.
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());
processor().manager().wait(thread::current().id(), pid);
processor().yield_now();
processor().manager().wait_done(thread::current().id(), pid);
} else {
println!("Program not exist");
}
//break;
}
unsafe { dealloc(buf.as_mut_ptr(), layout) };
}

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

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

Loading…
Cancel
Save