Fix a potential racing in park() and unpark(), fix sys_poll for a running telnet

master
Jiajie Chen 6 years ago
parent 9e6483f488
commit 8b9aecca1c

@ -131,14 +131,14 @@ impl ThreadPool {
/// Insert/Remove it to/from scheduler if necessary. /// Insert/Remove it to/from scheduler if necessary.
fn set_status(&self, tid: Tid, status: Status) { fn set_status(&self, tid: Tid, status: Status) {
let mut proc_lock = self.threads[tid].lock(); let mut proc_lock = self.threads[tid].lock();
let mut proc = proc_lock.as_mut().expect("process not exist"); if let Some(mut proc) = proc_lock.as_mut() {
trace!("process {} {:?} -> {:?}", tid, proc.status, status); trace!("process {} {:?} -> {:?}", tid, proc.status, status);
match (&proc.status, &status) { match (&proc.status, &status) {
(Status::Ready, Status::Ready) => return, (Status::Ready, Status::Ready) => return,
(Status::Ready, _) => panic!("can not remove a process from ready queue"), (Status::Ready, _) => panic!("can not remove a process from ready queue"),
(Status::Exited(_), _) => panic!("can not set status for a exited process"), (Status::Exited(_), _) => panic!("can not set status for a exited process"),
(Status::Sleeping, Status::Exited(_)) => self.timer.lock().stop(Event::Wakeup(tid)), (Status::Sleeping, Status::Exited(_)) => self.timer.lock().stop(Event::Wakeup(tid)),
(Status::Running(_), Status::Ready) => {} // to stop a thread, use stop() intead (Status::Running(_), Status::Ready) => {} // process will be added to scheduler in stop()
(_, Status::Ready) => self.scheduler.push(tid), (_, Status::Ready) => self.scheduler.push(tid),
_ => {} _ => {}
} }
@ -151,6 +151,7 @@ impl ThreadPool {
_ => {} _ => {}
} }
} }
}
pub fn get_status(&self, tid: Tid) -> Option<Status> { pub fn get_status(&self, tid: Tid) -> Option<Status> {
self.threads[tid].lock().as_ref().map(|p| p.status.clone()) self.threads[tid].lock().as_ref().map(|p| p.status.clone())

@ -72,7 +72,8 @@ pub fn backtrace() {
// Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate) // Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate)
// size = 512 pages // size = 512 pages
current_fp = *(current_fp as *const usize).offset(0); current_fp = *(current_fp as *const usize).offset(0);
if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>() { if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>() &&
current_fp <= 0xffff_ff00_0000_0000 {
break; break;
} }
current_pc = *(current_fp as *const usize).offset(1); current_pc = *(current_fp as *const usize).offset(1);

@ -62,13 +62,15 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
loop { loop {
use PollEvents as PE; use PollEvents as PE;
let mut proc = process(); let mut proc = process();
let mut events = 0;
for poll in polls.iter_mut() { for poll in polls.iter_mut() {
poll.revents = PE::NONE;
match proc.files.get(&(poll.fd as usize)) { match proc.files.get(&(poll.fd as usize)) {
Some(FileLike::File(_)) => { Some(FileLike::File(_)) => {
// FIXME: assume it is stdin for now // FIXME: assume it is stdin for now
if poll.events.contains(PE::IN) && STDIN.can_read() { if poll.events.contains(PE::IN) && STDIN.can_read() {
poll.revents = PE::IN; poll.revents = poll.revents | PE::IN;
return Ok(0); events = events + 1;
} }
}, },
Some(FileLike::Socket(wrapper)) => { Some(FileLike::Socket(wrapper)) => {
@ -78,29 +80,42 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
let mut socket = sockets.get::<TcpSocket>(wrapper.handle); let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
if !socket.is_open() { if !socket.is_open() {
poll.revents = PE::HUP; poll.revents = poll.revents | PE::HUP;
return Ok(0); events = events + 1;
} else if socket.can_recv() && poll.events.contains(PE::IN) { } else {
poll.revents = PE::IN; if socket.can_recv() && poll.events.contains(PE::IN) {
return Ok(0); poll.revents = poll.revents | PE::IN;
} else if socket.can_send() && poll.events.contains(PE::OUT) { events = events + 1;
poll.revents = PE::OUT; }
return Ok(0);
if socket.can_send() && poll.events.contains(PE::OUT) {
poll.revents = poll.revents | PE::OUT;
events = events + 1;
}
} }
} else { } else {
unimplemented!() unimplemented!()
} }
} }
None => { None => {
poll.revents = PE::ERR; poll.revents = poll.revents | PE::ERR;
return Ok(0); events = events + 1;
} }
} }
} }
drop(proc); drop(proc);
if events > 0 {
return Ok(events as isize);
}
let current_time_ms = unsafe {crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000};
if timeout_msecs < (1 << 31) && current_time_ms - begin_time_ms > timeout_msecs {
return Ok(0);
}
Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]); Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]);
} }
Ok(nfds as isize)
} }
pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult { pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult {
@ -704,6 +719,8 @@ pub struct PollFd {
bitflags! { bitflags! {
pub struct PollEvents: u16 { pub struct PollEvents: u16 {
/// Nothing Happens
const NONE = 0x0000;
/// There is data to read. /// There is data to read.
const IN = 0x0001; const IN = 0x0001;
/// Writing is now possible. /// Writing is now possible.

@ -294,6 +294,7 @@ pub fn sys_read_socket(proc: &mut Process, fd: usize, base: *mut u8, len: usize)
// avoid deadlock // avoid deadlock
drop(socket); drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait() SOCKET_ACTIVITY._wait()
} }
} else if let SocketType::Udp = wrapper.socket_type { } else if let SocketType::Udp = wrapper.socket_type {

Loading…
Cancel
Save