Skip to content

Commit 399f818

Browse files
authored
Merge pull request #1722 from cagatay-y/sched-opt
sched: don't alloc when waking blocked tasks up
2 parents eeab056 + 43b12b6 commit 399f818

File tree

2 files changed

+32
-47
lines changed

2 files changed

+32
-47
lines changed

src/scheduler/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,8 @@ impl PerCoreScheduler {
399399
pub fn handle_waiting_tasks(&mut self) {
400400
without_interrupts(|| {
401401
crate::executor::run();
402-
for task in self.blocked_tasks.handle_waiting_tasks() {
403-
self.ready_queue.push(task);
404-
}
402+
self.blocked_tasks
403+
.handle_waiting_tasks(&mut self.ready_queue);
405404
});
406405
}
407406

src/scheduler/task.rs

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use alloc::boxed::Box;
55
use alloc::collections::{LinkedList, VecDeque};
66
use alloc::rc::Rc;
77
use alloc::sync::Arc;
8-
use alloc::vec::Vec;
98
use core::cell::RefCell;
109
use core::num::NonZeroU64;
1110
use core::{cmp, fmt};
@@ -535,7 +534,7 @@ impl BlockedTaskQueue {
535534
}
536535
}
537536

538-
fn wakeup_task(task: Rc<RefCell<Task>>) {
537+
fn mark_ready(task: &RefCell<Task>) {
539538
let mut borrowed = task.borrow_mut();
540539
debug!(
541540
"Waking up task {} on core {}",
@@ -674,7 +673,7 @@ impl BlockedTaskQueue {
674673
}
675674

676675
// Wake it up.
677-
Self::wakeup_task(task_ref.clone());
676+
Self::mark_ready(&task_ref);
678677

679678
return task_ref;
680679
}
@@ -690,7 +689,7 @@ impl BlockedTaskQueue {
690689
///
691690
/// Should be called by the One-Shot Timer interrupt handler when the wakeup time for
692691
/// at least one task has elapsed.
693-
pub fn handle_waiting_tasks(&mut self) -> Vec<Rc<RefCell<Task>>> {
692+
pub fn handle_waiting_tasks(&mut self, ready_queue: &mut PriorityTaskQueue) {
694693
// Get the current time.
695694
let time = arch::processor::get_timer_ticks();
696695

@@ -703,48 +702,35 @@ impl BlockedTaskQueue {
703702
}
704703
}
705704

706-
let mut tasks = vec![];
707-
708-
// Loop through all blocked tasks.
709-
let mut cursor = self.list.cursor_front_mut();
710-
while let Some(node) = cursor.current() {
711-
// Get the wakeup time of this task and check if we have reached the first task
712-
// that hasn't elapsed yet or waits indefinitely.
713-
let node_wakeup_time = node.wakeup_time;
714-
if node_wakeup_time.is_none() || time < node_wakeup_time.unwrap() {
715-
break;
716-
}
717-
718-
// Otherwise, this task has elapsed, so remove it from the list and wake it up.
719-
tasks.push(node.task.clone());
720-
cursor.remove_current();
705+
// Get the wakeup time of this task and check if we have reached the first task
706+
// that hasn't elapsed yet or waits indefinitely.
707+
// This iterator has to be consumed to actually remove the elements.
708+
let newly_ready_tasks = self.list.extract_if(|blocked_task| {
709+
blocked_task
710+
.wakeup_time
711+
.is_some_and(|wakeup_time| wakeup_time < time)
712+
});
713+
714+
for task in newly_ready_tasks {
715+
Self::mark_ready(&task.task);
716+
ready_queue.push(task.task);
721717
}
722718

723-
#[cfg(any(feature = "tcp", feature = "udp"))]
724-
arch::set_oneshot_timer(cursor.current().map_or_else(
725-
|| self.network_wakeup_time,
726-
|node| match node.wakeup_time {
727-
Some(wt) => {
728-
if let Some(timer) = self.network_wakeup_time {
729-
if wt < timer { Some(wt) } else { Some(timer) }
730-
} else {
731-
Some(wt)
732-
}
733-
}
734-
None => self.network_wakeup_time,
735-
},
736-
));
737-
#[cfg(not(any(feature = "tcp", feature = "udp")))]
738-
arch::set_oneshot_timer(
739-
cursor
740-
.current()
741-
.map_or_else(|| None, |node| node.wakeup_time),
742-
);
743-
744-
for task in tasks.iter().cloned() {
745-
Self::wakeup_task(task);
746-
}
719+
let new_task_wakeup_time = self.list.front().and_then(|task| task.wakeup_time);
720+
cfg_if::cfg_if! {
721+
if #[cfg(any(feature = "tcp", feature = "udp"))] {
722+
let network_wakeup_time = self.network_wakeup_time;
723+
} else {
724+
let network_wakeup_time = None;
725+
}
726+
};
727+
let timer_wakeup_time = match (new_task_wakeup_time, network_wakeup_time) {
728+
(None, None) => None,
729+
(None, Some(network_wt)) => Some(network_wt),
730+
(Some(task_wt), None) => Some(task_wt),
731+
(Some(task_wt), Some(network_wt)) => Some(u64::min(task_wt, network_wt)),
732+
};
747733

748-
tasks
734+
arch::set_oneshot_timer(timer_wakeup_time);
749735
}
750736
}

0 commit comments

Comments
 (0)