debug for sleepkill

master
chenqiuhao 6 years ago
parent 5ee44588e0
commit 8d6d3b7c37

@ -1,4 +1,4 @@
use alloc::collections::BinaryHeap;
use alloc::collections::VecDeque;
use core::cmp::{Ordering, PartialOrd};
type Time = usize;
@ -30,32 +30,63 @@ impl<T> Ord for Timer<T> {
pub struct EventHub<T> {
tick: Time,
timers: BinaryHeap<Timer<T>>,
timers: VecDeque<Timer<T>>,
}
impl<T> EventHub<T> {
impl<T: PartialEq> EventHub<T> {
pub fn new() -> Self {
EventHub {
tick: 0,
timers: BinaryHeap::new(),
timers: VecDeque::new(),
}
}
pub fn tick(&mut self) {
self.tick += 1;
}
pub fn pop(&mut self) -> Option<T> {
match self.timers.peek() {
match self.timers.front() {
None => return None,
Some(timer) if timer.time != self.tick => return None,
_ => {}
};
self.timers.pop().map(|t| t.data)
self.timers.pop_front().map(|t| t.data)
}
pub fn push(&mut self, time_after: Time, data: T) {
//debug!("{:?} {:?}", self.tick, time_after);
let time = self.tick + time_after;
self.timers.push(Timer { time, data });
let timer = Timer { time, data };
let mut it = self.timers.iter();
let mut i : usize = 0;
loop {
let now = it.next();
if now == None {
break
};
if now.unwrap() < &timer {
break
};
i += 1;
}
self.timers.insert(i, timer);
}
pub fn get_time(&self) -> Time {
self.tick
}
pub fn remove(&mut self, data: T) {
let mut it = self.timers.iter();
let mut i : usize = 0;
loop {
let now = it.next();
if now == None {
break
};
if now.map(|t| &t.data).unwrap() == &data {
break
};
i += 1;
}
if i < self.timers.len() {
self.timers.remove(i);
}
}
}

@ -26,10 +26,11 @@ pub enum Status {
Exited(ExitCode),
}
#[derive(Eq, PartialEq)]
enum Event {
Wakeup(Pid),
Dropped,
}
pub trait Context {
unsafe fn switch_to(&mut self, target: &mut Context);
}
@ -84,6 +85,7 @@ impl ProcessManager {
while let Some(event) = event_hub.pop() {
match event {
Event::Wakeup(pid) => self.set_status(pid, Status::Ready),
Event::Dropped => {},
}
}
self.scheduler.lock().tick(pid)
@ -126,20 +128,22 @@ impl ProcessManager {
/// Switch the status of a process.
/// Insert/Remove it to/from scheduler if necessary.
fn set_status(&self, pid: Pid, status: Status) {
let mut scheduler = self.scheduler.lock();
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);
match (&proc.status, &status) {
(Status::Ready, Status::Ready) => return,
(Status::Ready, _) => scheduler.remove(pid),
(Status::Running(_), _) => {},
(Status::Exited(_), _) => panic!("can not set status for a exited process"),
(Status::Waiting(target), Status::Exited(_)) =>
self.wait_queue[*target].lock().retain(|&i| i != pid),
// TODO: Sleep -> Exited Remove wakeup event.
(_, Status::Ready) => scheduler.insert(pid),
_ => {}
{ // limit the lifetime of scheduler
let mut scheduler = self.scheduler.lock();
match (&proc.status, &status) {
(Status::Ready, Status::Ready) => return,
(Status::Ready, _) => scheduler.remove(pid),
(Status::Running(_), _) => {},
(Status::Exited(_), _) => panic!("can not set status for a exited process"),
(Status::Waiting(target), Status::Exited(_)) =>
self.wait_queue[*target].lock().retain(|&i| i != pid),
(Status::Sleeping, Status::Exited(_)) => self.event_hub.lock().remove(Event::Wakeup(pid)),
(_, Status::Ready) => scheduler.insert(pid),
_ => {}
}
}
match proc.status {
Status::Running(_) => proc.status_after_stop = status,
@ -165,8 +169,9 @@ impl ProcessManager {
}
}
pub fn sleep(&self, pid: Pid, time: usize) {
pub fn sleep(&self, pid: Pid, time_raw: usize) {
self.set_status(pid, Status::Sleeping);
let time = if time_raw >= (1 << 31) {0} else {time_raw};
if time != 0 {
self.event_hub.lock().push(time, Event::Wakeup(pid));
}
@ -183,7 +188,7 @@ impl ProcessManager {
pub fn exit(&self, pid: Pid, code: ExitCode) {
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(..) {

@ -1 +1 @@
Subproject commit a37a65fa13a00c5aa0068c3f2b5d55af6a37dd93
Subproject commit f358204af01f2374ab6ed6ea059f724cd5f2fe6f

@ -45,8 +45,12 @@ pub fn shell() {
// start interaction
loop {
print!(">> ");
use console::get_line;
let name = get_line();
//use alloc::prelude::ToString;
//let name = "waitkill".to_string();
if name == "" {
continue;
}

@ -113,7 +113,7 @@ fn sys_yield() -> i32 {
/// Kill the process
fn sys_kill(pid: usize) -> i32 {
info!("kill: {}", pid);
info!("{} killed: {}", thread::current().id(), pid);
processor().manager().exit(pid, 0x100);
if pid == thread::current().id() {
processor().yield_now();

Loading…
Cancel
Save