Skip to content

Commit

Permalink
fix(task): don't access scheduler from BlockedTaskQueue::wakeup_task
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <[email protected]>
  • Loading branch information
mkroening committed Sep 14, 2023
1 parent 3f8bc62 commit dbab4db
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 33 deletions.
17 changes: 13 additions & 4 deletions src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,19 +293,27 @@ impl PerCoreScheduler {
pub fn handle_waiting_tasks(&mut self) {
without_interrupts(|| {
crate::executor::run();
self.blocked_tasks.handle_waiting_tasks();
for task in self.blocked_tasks.handle_waiting_tasks() {
self.ready_queue.push(task);
}
});
}

#[cfg(not(feature = "smp"))]
pub fn custom_wakeup(&mut self, task: TaskHandle) {
without_interrupts(|| self.blocked_tasks.custom_wakeup(task));
without_interrupts(|| {
let task = self.blocked_tasks.custom_wakeup(task);
self.ready_queue.push(task);
});
}

#[cfg(feature = "smp")]
pub fn custom_wakeup(&mut self, task: TaskHandle) {
if task.get_core_id() == self.core_id {
without_interrupts(|| self.blocked_tasks.custom_wakeup(task));
without_interrupts(|| {
let task = self.blocked_tasks.custom_wakeup(task);
self.ready_queue.push(task);
});
} else {
get_scheduler_input(task.get_core_id())
.lock()
Expand Down Expand Up @@ -447,7 +455,8 @@ impl PerCoreScheduler {
let mut input_locked = CoreLocal::get().scheduler_input.lock();

while let Some(task) = input_locked.wakeup_tasks.pop_front() {
self.blocked_tasks.custom_wakeup(task);
let task = self.blocked_tasks.custom_wakeup(task);
self.ready_queue.push(task);
}

while let Some(new_task) = input_locked.new_tasks.pop_front() {
Expand Down
65 changes: 36 additions & 29 deletions src/scheduler/task.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use alloc::boxed::Box;
use alloc::collections::{LinkedList, VecDeque};
use alloc::rc::Rc;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::cmp::Ordering;
use core::fmt;
Expand Down Expand Up @@ -463,31 +464,26 @@ impl BlockedTaskQueue {
}

fn wakeup_task(task: Rc<RefCell<Task>>) {
{
let mut borrowed = task.borrow_mut();
debug!(
"Waking up task {} on core {}",
borrowed.id, borrowed.core_id
);

assert!(
borrowed.core_id == core_id(),
"Try to wake up task {} on the wrong core {} != {}",
borrowed.id,
borrowed.core_id,
core_id()
);
let mut borrowed = task.borrow_mut();
debug!(
"Waking up task {} on core {}",
borrowed.id, borrowed.core_id
);

assert!(
borrowed.status == TaskStatus::Blocked,
"Trying to wake up task {} which is not blocked",
borrowed.id
);
borrowed.status = TaskStatus::Ready;
}
assert!(
borrowed.core_id == core_id(),
"Try to wake up task {} on the wrong core {} != {}",
borrowed.id,
borrowed.core_id,
core_id()
);

// Add the task to the ready queue.
core_scheduler().ready_queue.push(task);
assert!(
borrowed.status == TaskStatus::Blocked,
"Trying to wake up task {} which is not blocked",
borrowed.id
);
borrowed.status = TaskStatus::Ready;
}

#[cfg(any(feature = "tcp", feature = "udp"))]
Expand Down Expand Up @@ -574,7 +570,7 @@ impl BlockedTaskQueue {
}

/// Manually wake up a blocked task.
pub fn custom_wakeup(&mut self, task: TaskHandle) {
pub fn custom_wakeup(&mut self, task: TaskHandle) -> Rc<RefCell<Task>> {
let mut first_task = true;
let mut cursor = self.list.cursor_front_mut();

Expand All @@ -588,8 +584,8 @@ impl BlockedTaskQueue {
// Loop through all blocked tasks to find it.
while let Some(node) = cursor.current() {
if node.task.borrow().id == task.get_id() {
// Remove it from the list of blocked tasks and wake it up.
Self::wakeup_task(node.task.clone());
// Remove it from the list of blocked tasks.
let task_ref = node.task.clone();
cursor.remove_current();

// If this is the first task, adjust the One-Shot Timer to fire at the
Expand Down Expand Up @@ -623,7 +619,10 @@ impl BlockedTaskQueue {
);
}

return;
// Wake it up.
Self::wakeup_task(task_ref.clone());

return task_ref;
}

first_task = false;
Expand All @@ -637,7 +636,7 @@ impl BlockedTaskQueue {
///
/// Should be called by the One-Shot Timer interrupt handler when the wakeup time for
/// at least one task has elapsed.
pub fn handle_waiting_tasks(&mut self) {
pub fn handle_waiting_tasks(&mut self) -> Vec<Rc<RefCell<Task>>> {
// Get the current time.
let time = arch::processor::get_timer_ticks();

Expand All @@ -650,6 +649,8 @@ impl BlockedTaskQueue {
}
}

let mut tasks = vec![];

// Loop through all blocked tasks.
let mut cursor = self.list.cursor_front_mut();
while let Some(node) = cursor.current() {
Expand All @@ -661,7 +662,7 @@ impl BlockedTaskQueue {
}

// Otherwise, this task has elapsed, so remove it from the list and wake it up.
Self::wakeup_task(node.task.clone());
tasks.push(node.task.clone());
cursor.remove_current();
}

Expand Down Expand Up @@ -689,5 +690,11 @@ impl BlockedTaskQueue {
.current()
.map_or_else(|| None, |node| node.wakeup_time),
);

for task in tasks.iter().cloned() {
Self::wakeup_task(task);
}

tasks
}
}

0 comments on commit dbab4db

Please sign in to comment.