Fix sys_wait. Pass `exit` & `sleep`.

master
WangRunji 7 years ago
parent db8cd7b786
commit 8f306edd85

@ -15,6 +15,9 @@ pub struct Process {
pub(in process) status: Status, pub(in process) status: Status,
pub(in process) rsp: usize, pub(in process) rsp: usize,
pub(in process) is_user: bool, pub(in process) is_user: bool,
/// Set (addr, value) after switch.
/// Used to set wait error code.
pub(in process) set_value: Option<(usize, usize)>,
} }
pub type Pid = usize; pub type Pid = usize;
@ -46,6 +49,7 @@ impl Process {
status: Status::Ready, status: Status::Ready,
rsp, rsp,
is_user: false, is_user: false,
set_value: None,
} }
} }
@ -63,6 +67,7 @@ impl Process {
status: Status::Running, status: Status::Running,
rsp: 0, // will be set at first schedule rsp: 0, // will be set at first schedule
is_user: false, is_user: false,
set_value: None,
} }
} }
@ -133,6 +138,7 @@ impl Process {
status: Status::Ready, status: Status::Ready,
rsp, rsp,
is_user: true, is_user: true,
set_value: None,
} }
} }
@ -173,6 +179,7 @@ impl Process {
status: Status::Ready, status: Status::Ready,
rsp, rsp,
is_user: true, is_user: true,
set_value: None,
} }
} }

@ -135,6 +135,10 @@ impl Processor {
*from_pt = Some(old_table); *from_pt = Some(old_table);
} }
if let Some((addr, value)) = to.set_value.take() {
unsafe { *(addr as *mut usize) = value; }
}
info!("Processor: switch from {} to {}\n rsp: {:#x} -> {:#x}", pid0, pid, rsp0, rsp); info!("Processor: switch from {} to {}\n rsp: {:#x} -> {:#x}", pid0, pid, rsp0, rsp);
} }
@ -159,10 +163,13 @@ impl Processor {
info!("Processor: {} exit, code: {}", pid, error_code); info!("Processor: {} exit, code: {}", pid, error_code);
self.get_mut(pid).status = Status::Exited(error_code); self.get_mut(pid).status = Status::Exited(error_code);
if let Some(waiter) = self.find_waiter(pid) { if let Some(waiter) = self.find_waiter(pid) {
info!(" then wakeup {}", waiter);
self.next = Some(waiter);
{ {
let p = self.get_mut(waiter); let p = self.get_mut(waiter);
p.set_value.as_mut().unwrap().1 = error_code;
p.status = Status::Ready; p.status = Status::Ready;
p.set_return_value(error_code); p.set_return_value(0);
} }
// FIXME: remove this process // FIXME: remove this process
self.get_mut(pid).parent = 0; self.get_mut(pid).parent = 0;
@ -177,7 +184,7 @@ impl Processor {
} }
/// Let current process wait for another /// Let current process wait for another
pub fn current_wait_for(&mut self, target: WaitTarget) -> WaitResult { pub fn current_wait_for(&mut self, target: WaitTarget, code: *mut i32) -> WaitResult {
info!("Processor: current {} wait for {:?}", self.current_pid, target); info!("Processor: current {} wait for {:?}", self.current_pid, target);
// Find one target process and it's exit code // Find one target process and it's exit code
let (pid, exit_code) = match target { let (pid, exit_code) = match target {
@ -197,11 +204,17 @@ impl Processor {
if let Some(exit_code) = exit_code { if let Some(exit_code) = exit_code {
info!("Processor: {} wait find and remove {}", self.current_pid, pid); info!("Processor: {} wait find and remove {}", self.current_pid, pid);
self.procs.remove(&pid); self.procs.remove(&pid);
if !code.is_null() {
// WARNING: must be current! (page table)
unsafe { *code = exit_code as i32 };
}
WaitResult::Ok(pid, exit_code) WaitResult::Ok(pid, exit_code)
} else { } else {
info!("Processor: {} wait for {}", self.current_pid, pid); info!("Processor: {} wait for {}", self.current_pid, pid);
let current_pid = self.current_pid; let current_pid = self.current_pid;
self.get_mut(current_pid).status = Status::Waiting(pid); let p = self.get_mut(current_pid);
p.status = Status::Waiting(pid);
p.set_value = Some((code as usize, 0));
WaitResult::Blocked WaitResult::Blocked
} }
} }

@ -98,14 +98,9 @@ fn sys_wait(pid: usize, code: *mut i32) -> i32 {
0 => WaitTarget::AnyChild, 0 => WaitTarget::AnyChild,
_ => WaitTarget::Proc(pid), _ => WaitTarget::Proc(pid),
}; };
match processor.current_wait_for(target) { match processor.current_wait_for(target, code) {
WaitResult::Ok(pid, error_code) => { WaitResult::Ok(pid, error_code) => 0,
if !code.is_null() { WaitResult::Blocked => 0,
unsafe { *code = error_code as i32 };
}
0 // pid as i32
},
WaitResult::Blocked => 0, // unused
WaitResult::NotExist => -1, WaitResult::NotExist => -1,
} }
} }

@ -2,7 +2,7 @@
- [ ] badarg - [ ] badarg
- [ ] badsegment - [ ] badsegment
- [x] divzero - [x] divzero
- [ ] exit - [x] exit
- [x] faultread - [x] faultread
- [x] faultreadkernel - [x] faultreadkernel
- [x] forktest - [x] forktest
@ -13,10 +13,28 @@
- [ ] pgdir - [ ] pgdir
- [ ] priority - [ ] priority
- [ ] sh - [ ] sh
- [ ] sleep - [x] sleep
- [x] sleepkill - [x] sleepkill
- [x] softint - [x] softint
- [x] spin - [x] spin
- [x] testbss - [x] testbss
- [x] waitkill - [x] waitkill
- [x] yield - [x] yield
## xv6 64bit user programs pass status
- [ ] cat
- [ ] chmod
- [ ] echo
- [ ] forktest
- [ ] grep
- [ ] init
- [ ] kill
- [ ] ln
- [ ] ls
- [ ] mkdir
- [ ] rm
- [ ] sh
- [ ] stressfs
- [ ] usertests
- [ ] wc
- [ ] zombie

Loading…
Cancel
Save