@@ -5,7 +5,6 @@ use alloc::boxed::Box;
5
5
use alloc:: collections:: { LinkedList , VecDeque } ;
6
6
use alloc:: rc:: Rc ;
7
7
use alloc:: sync:: Arc ;
8
- use alloc:: vec:: Vec ;
9
8
use core:: cell:: RefCell ;
10
9
use core:: num:: NonZeroU64 ;
11
10
use core:: { cmp, fmt} ;
@@ -535,7 +534,7 @@ impl BlockedTaskQueue {
535
534
}
536
535
}
537
536
538
- fn wakeup_task ( task : Rc < RefCell < Task > > ) {
537
+ fn mark_ready ( task : & RefCell < Task > ) {
539
538
let mut borrowed = task. borrow_mut ( ) ;
540
539
debug ! (
541
540
"Waking up task {} on core {}" ,
@@ -674,7 +673,7 @@ impl BlockedTaskQueue {
674
673
}
675
674
676
675
// Wake it up.
677
- Self :: wakeup_task ( task_ref. clone ( ) ) ;
676
+ Self :: mark_ready ( & task_ref) ;
678
677
679
678
return task_ref;
680
679
}
@@ -690,7 +689,7 @@ impl BlockedTaskQueue {
690
689
///
691
690
/// Should be called by the One-Shot Timer interrupt handler when the wakeup time for
692
691
/// 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 ) {
694
693
// Get the current time.
695
694
let time = arch:: processor:: get_timer_ticks ( ) ;
696
695
@@ -703,48 +702,35 @@ impl BlockedTaskQueue {
703
702
}
704
703
}
705
704
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 ) ;
721
717
}
722
718
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
+ } ;
747
733
748
- tasks
734
+ arch :: set_oneshot_timer ( timer_wakeup_time ) ;
749
735
}
750
736
}
0 commit comments