|
|
@ -33,8 +33,6 @@ pub struct Processor_<T: Context, S: Scheduler> {
|
|
|
|
procs: BTreeMap<Pid, Process<T>>,
|
|
|
|
procs: BTreeMap<Pid, Process<T>>,
|
|
|
|
current_pid: Pid,
|
|
|
|
current_pid: Pid,
|
|
|
|
event_hub: EventHub<Event>,
|
|
|
|
event_hub: EventHub<Event>,
|
|
|
|
/// Choose what on next schedule ?
|
|
|
|
|
|
|
|
next: Option<Pid>,
|
|
|
|
|
|
|
|
// WARNING: if MAX_PROCESS_NUM is too large, will cause stack overflow
|
|
|
|
// WARNING: if MAX_PROCESS_NUM is too large, will cause stack overflow
|
|
|
|
scheduler: S,
|
|
|
|
scheduler: S,
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -65,7 +63,6 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
current_pid: 0,
|
|
|
|
current_pid: 0,
|
|
|
|
event_hub: EventHub::new(),
|
|
|
|
event_hub: EventHub::new(),
|
|
|
|
next: None,
|
|
|
|
|
|
|
|
scheduler,
|
|
|
|
scheduler,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -74,7 +71,7 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
self.scheduler.set_priority(self.current_pid, priority);
|
|
|
|
self.scheduler.set_priority(self.current_pid, priority);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn set_reschedule(&mut self) {
|
|
|
|
pub fn yield_now(&mut self) {
|
|
|
|
let pid = self.current_pid;
|
|
|
|
let pid = self.current_pid;
|
|
|
|
self.set_status(pid, Status::Ready);
|
|
|
|
self.set_status(pid, Status::Ready);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -108,7 +105,7 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
pub fn tick(&mut self) {
|
|
|
|
pub fn tick(&mut self) {
|
|
|
|
let current_pid = self.current_pid;
|
|
|
|
let current_pid = self.current_pid;
|
|
|
|
if self.scheduler.tick(current_pid) {
|
|
|
|
if self.scheduler.tick(current_pid) {
|
|
|
|
self.set_reschedule();
|
|
|
|
self.yield_now();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.event_hub.tick();
|
|
|
|
self.event_hub.tick();
|
|
|
|
while let Some(event) = self.event_hub.pop() {
|
|
|
|
while let Some(event) = self.event_hub.pop() {
|
|
|
@ -116,12 +113,12 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
match event {
|
|
|
|
match event {
|
|
|
|
Event::Schedule => {
|
|
|
|
Event::Schedule => {
|
|
|
|
self.event_hub.push(10, Event::Schedule);
|
|
|
|
self.event_hub.push(10, Event::Schedule);
|
|
|
|
self.set_reschedule();
|
|
|
|
self.yield_now();
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Event::Wakeup(pid) => {
|
|
|
|
Event::Wakeup(pid) => {
|
|
|
|
self.set_status(pid, Status::Ready);
|
|
|
|
self.set_status(pid, Status::Ready);
|
|
|
|
self.set_reschedule();
|
|
|
|
self.yield_now();
|
|
|
|
self.next = Some(pid);
|
|
|
|
self.scheduler.move_to_head(pid);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -150,13 +147,13 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
if self.get(self.current_pid).status == Status::Running {
|
|
|
|
if self.get(self.current_pid).status == Status::Running {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let pid = self.next.take().unwrap_or_else(|| self.scheduler.select().unwrap());
|
|
|
|
let pid = self.scheduler.select().unwrap();
|
|
|
|
self.switch_to(pid);
|
|
|
|
self.switch_to(pid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Switch process to `pid`, switch page table if necessary.
|
|
|
|
/// Switch to process `pid`.
|
|
|
|
/// Store `rsp` and point it to target kernel stack.
|
|
|
|
|
|
|
|
/// The current status must be set before, and not be `Running`.
|
|
|
|
/// The current status must be set before, and not be `Running`.
|
|
|
|
|
|
|
|
/// The target status must be `Ready`.
|
|
|
|
fn switch_to(&mut self, pid: Pid) {
|
|
|
|
fn switch_to(&mut self, pid: Pid) {
|
|
|
|
// for debug print
|
|
|
|
// for debug print
|
|
|
|
let pid0 = self.current_pid;
|
|
|
|
let pid0 = self.current_pid;
|
|
|
@ -203,7 +200,7 @@ impl<T: Context, S: Scheduler> Processor_<T, S> {
|
|
|
|
if let Some(waiter) = self.find_waiter(pid) {
|
|
|
|
if let Some(waiter) = self.find_waiter(pid) {
|
|
|
|
info!(" then wakeup {}", waiter);
|
|
|
|
info!(" then wakeup {}", waiter);
|
|
|
|
self.set_status(waiter, Status::Ready);
|
|
|
|
self.set_status(waiter, Status::Ready);
|
|
|
|
self.next = Some(waiter);
|
|
|
|
self.scheduler.move_to_head(waiter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|