From af32258eb36e60c2b3ea5948d366e19e9089f9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 6 Oct 2023 09:52:17 +0200 Subject: [PATCH 1/2] Revert "Revert "fix(core_local): put scheduler into RefCell"" This reverts commit fd94856d3cee411e061d9462b016d8a0394a6ae8. --- src/arch/aarch64/kernel/core_local.rs | 17 ++++++++-------- src/arch/x86_64/kernel/apic.rs | 2 +- src/arch/x86_64/kernel/core_local.rs | 14 +++++++------ src/scheduler/mod.rs | 29 ++++++++++++++------------- src/synch/futex.rs | 18 +++++++++-------- src/synch/recmutex.rs | 4 ++-- src/synch/semaphore.rs | 2 +- src/syscalls/tasks.rs | 4 ++-- 8 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/arch/aarch64/kernel/core_local.rs b/src/arch/aarch64/kernel/core_local.rs index a700972923..44d4dffede 100644 --- a/src/arch/aarch64/kernel/core_local.rs +++ b/src/arch/aarch64/kernel/core_local.rs @@ -1,7 +1,7 @@ use alloc::boxed::Box; use alloc::vec::Vec; use core::arch::asm; -use core::cell::{Cell, RefCell, RefMut}; +use core::cell::{RefCell, RefMut}; use core::ptr; use core::sync::atomic::Ordering; @@ -20,7 +20,7 @@ pub(crate) struct CoreLocal { /// ID of the current Core. core_id: CoreId, /// Scheduler of the current Core. - scheduler: Cell<*mut PerCoreScheduler>, + scheduler: RefCell>, /// Interface to the interrupt counters irq_statistics: &'static IrqStatistics, /// Queue of async tasks @@ -44,7 +44,7 @@ impl CoreLocal { let this = Self { this: ptr::null_mut(), core_id, - scheduler: Cell::new(ptr::null_mut()), + scheduler: RefCell::new(None), irq_statistics, async_tasks: RefCell::new(Vec::new()), #[cfg(feature = "smp")] @@ -91,17 +91,18 @@ pub(crate) fn core_id() -> CoreId { } } -#[inline] -pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler { - unsafe { &mut *CoreLocal::get().scheduler.get() } +pub(crate) fn core_scheduler() -> RefMut<'static, PerCoreScheduler> { + RefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { + scheduler.as_mut().unwrap() + }) } pub(crate) fn async_tasks() -> RefMut<'static, Vec> { CoreLocal::get().async_tasks.borrow_mut() } -pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) { - CoreLocal::get().scheduler.set(scheduler); +pub(crate) fn set_core_scheduler(scheduler: PerCoreScheduler) { + *CoreLocal::get().scheduler.borrow_mut() = Some(scheduler); } pub(crate) fn increment_irq_counter(irq_no: u8) { diff --git a/src/arch/x86_64/kernel/apic.rs b/src/arch/x86_64/kernel/apic.rs index 78b0a48198..3d66c15804 100644 --- a/src/arch/x86_64/kernel/apic.rs +++ b/src/arch/x86_64/kernel/apic.rs @@ -229,7 +229,7 @@ extern "x86-interrupt" fn wakeup_handler(_stack_frame: interrupts::ExceptionStac debug!("Received Wakeup Interrupt"); increment_irq_counter(WAKEUP_INTERRUPT_NUMBER); - let core_scheduler = core_scheduler(); + let mut core_scheduler = core_scheduler(); core_scheduler.check_input(); eoi(); if core_scheduler.is_scheduling() { diff --git a/src/arch/x86_64/kernel/core_local.rs b/src/arch/x86_64/kernel/core_local.rs index bf6210f5fa..50509a9e22 100644 --- a/src/arch/x86_64/kernel/core_local.rs +++ b/src/arch/x86_64/kernel/core_local.rs @@ -24,7 +24,7 @@ pub(crate) struct CoreLocal { /// Sequential ID of this CPU Core. core_id: CoreId, /// Scheduler for this CPU Core. - scheduler: Cell<*mut PerCoreScheduler>, + scheduler: RefCell>, /// Task State Segment (TSS) allocated for this CPU Core. pub tss: Cell<*mut TaskStateSegment>, /// start address of the kernel stack @@ -54,7 +54,7 @@ impl CoreLocal { let this = Self { this: ptr::null_mut(), core_id, - scheduler: Cell::new(ptr::null_mut()), + scheduler: RefCell::new(None), tss: Cell::new(ptr::null_mut()), kernel_stack: Cell::new(0), irq_statistics, @@ -101,16 +101,18 @@ pub(crate) fn core_id() -> CoreId { } } -pub(crate) fn core_scheduler() -> &'static mut PerCoreScheduler { - unsafe { &mut *CoreLocal::get().scheduler.get() } +pub(crate) fn core_scheduler() -> RefMut<'static, PerCoreScheduler> { + RefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { + scheduler.as_mut().unwrap() + }) } pub(crate) fn async_tasks() -> RefMut<'static, Vec> { CoreLocal::get().async_tasks.borrow_mut() } -pub(crate) fn set_core_scheduler(scheduler: *mut PerCoreScheduler) { - CoreLocal::get().scheduler.set(scheduler); +pub(crate) fn set_core_scheduler(scheduler: PerCoreScheduler) { + *CoreLocal::get().scheduler.borrow_mut() = Some(scheduler); } pub(crate) fn increment_irq_counter(irq_no: u8) { diff --git a/src/scheduler/mod.rs b/src/scheduler/mod.rs index b939d08e0e..53b75993e9 100644 --- a/src/scheduler/mod.rs +++ b/src/scheduler/mod.rs @@ -1,9 +1,8 @@ -use alloc::boxed::Box; use alloc::collections::{BTreeMap, VecDeque}; use alloc::rc::Rc; #[cfg(feature = "smp")] use alloc::vec::Vec; -use core::cell::RefCell; +use core::cell::{RefCell, RefMut}; use core::sync::atomic::{AtomicU32, Ordering}; use crossbeam_utils::Backoff; @@ -88,9 +87,9 @@ pub trait PerCoreSchedulerExt { fn exit(self, exit_code: i32) -> !; } -impl PerCoreSchedulerExt for &mut PerCoreScheduler { +impl PerCoreSchedulerExt for RefMut<'_, PerCoreScheduler> { #[cfg(target_arch = "x86_64")] - fn reschedule(self) { + fn reschedule(mut self) { without_interrupts(|| { if let Some(last_stack_pointer) = self.scheduler() { let (new_stack_pointer, is_idle) = { @@ -102,10 +101,12 @@ impl PerCoreSchedulerExt for &mut PerCoreScheduler { }; if is_idle || Rc::ptr_eq(&self.current_task, &self.fpu_owner) { + drop(self); unsafe { switch_to_fpu_owner(last_stack_pointer, new_stack_pointer.as_usize()); } } else { + drop(self); unsafe { switch_to_task(last_stack_pointer, new_stack_pointer.as_usize()); } @@ -123,6 +124,8 @@ impl PerCoreSchedulerExt for &mut PerCoreScheduler { use crate::interrupts::SGI_RESCHED; + drop(self); + unsafe { asm!("dsb nsh", "isb", options(nostack, nomem, preserves_flags)); } @@ -142,13 +145,14 @@ impl PerCoreSchedulerExt for &mut PerCoreScheduler { } #[cfg(any(feature = "tcp", feature = "udp"))] - fn add_network_timer(self, wakeup_time: Option) { + fn add_network_timer(mut self, wakeup_time: Option) { without_interrupts(|| { self.blocked_tasks.add_network_timer(wakeup_time); + drop(self); }) } - fn exit(self, exit_code: i32) -> ! { + fn exit(mut self, exit_code: i32) -> ! { without_interrupts(|| { // Get the current task. let mut current_task_borrowed = self.current_task.borrow_mut(); @@ -538,7 +542,7 @@ impl PerCoreScheduler { let backoff = Backoff::new(); loop { - let core_scheduler = core_scheduler(); + let mut core_scheduler = core_scheduler(); interrupts::disable(); // run async tasks @@ -548,6 +552,7 @@ impl PerCoreScheduler { core_scheduler.cleanup_tasks(); if core_scheduler.ready_queue.is_empty() { + drop(core_scheduler); if backoff.is_completed() { interrupts::enable_and_wait(); } else { @@ -698,7 +703,7 @@ pub fn add_current_core() { "Initializing scheduler for core {} with idle task {}", core_id, tid ); - let boxed_scheduler = Box::new(PerCoreScheduler { + set_core_scheduler(PerCoreScheduler { #[cfg(feature = "smp")] core_id, current_task: idle_task.clone(), @@ -709,9 +714,6 @@ pub fn add_current_core() { finished_tasks: VecDeque::new(), blocked_tasks: BlockedTaskQueue::new(), }); - - let scheduler = Box::into_raw(boxed_scheduler); - set_core_scheduler(scheduler); #[cfg(feature = "smp")] { SCHEDULER_INPUTS.lock().insert( @@ -728,11 +730,9 @@ fn get_scheduler_input(core_id: CoreId) -> &'static InterruptTicketMutex Result<(), ()> { - let core_scheduler = core_scheduler(); - debug!( "Task {} is waiting for task {}", - core_scheduler.get_current_task_id(), + core_scheduler().get_current_task_id(), id ); @@ -740,6 +740,7 @@ pub fn join(id: TaskId) -> Result<(), ()> { let mut waiting_tasks_guard = WAITING_TASKS.lock(); if let Some(queue) = waiting_tasks_guard.get_mut(&id) { + let mut core_scheduler = core_scheduler(); queue.push_back(core_scheduler.get_current_task_handle()); core_scheduler.block_current_task(None); diff --git a/src/synch/futex.rs b/src/synch/futex.rs index ded2428357..a22d5a4ebe 100644 --- a/src/synch/futex.rs +++ b/src/synch/futex.rs @@ -52,14 +52,15 @@ pub(crate) fn futex_wait( timeout }; - let scheduler = core_scheduler(); + let mut scheduler = core_scheduler(); scheduler.block_current_task(wakeup_time); let handle = scheduler.get_current_task_handle(); parking_lot.entry(addr(address)).or_default().push(handle); drop(parking_lot); + drop(scheduler); loop { - scheduler.reschedule(); + core_scheduler().reschedule(); let mut parking_lot = PARKING_LOT.lock(); if matches!(wakeup_time, Some(t) if t <= get_timer_ticks()) { @@ -88,7 +89,7 @@ pub(crate) fn futex_wait( } else { // A spurious wakeup occurred, sleep again. // Tasks do not change core, so the handle in the parking lot is still current. - scheduler.block_current_task(wakeup_time); + core_scheduler().block_current_task(wakeup_time); } } drop(parking_lot); @@ -121,14 +122,15 @@ pub(crate) fn futex_wait_and_set( timeout }; - let scheduler = core_scheduler(); + let mut scheduler = core_scheduler(); scheduler.block_current_task(wakeup_time); let handle = scheduler.get_current_task_handle(); parking_lot.entry(addr(address)).or_default().push(handle); drop(parking_lot); + drop(scheduler); loop { - scheduler.reschedule(); + core_scheduler().reschedule(); let mut parking_lot = PARKING_LOT.lock(); if matches!(wakeup_time, Some(t) if t <= get_timer_ticks()) { @@ -157,7 +159,7 @@ pub(crate) fn futex_wait_and_set( } else { // A spurious wakeup occurred, sleep again. // Tasks do not change core, so the handle in the parking lot is still current. - scheduler.block_current_task(wakeup_time); + core_scheduler().block_current_task(wakeup_time); } } drop(parking_lot); @@ -178,7 +180,7 @@ pub(crate) fn futex_wake(address: &AtomicU32, count: i32) -> i32 { Entry::Vacant(_) => return 0, }; - let scheduler = core_scheduler(); + let mut scheduler = core_scheduler(); let mut woken = 0; while woken != count || count == i32::MAX { match queue.get_mut().pop() { @@ -213,7 +215,7 @@ pub(crate) fn futex_wake_or_set(address: &AtomicU32, count: i32, new_value: u32) } }; - let scheduler = core_scheduler(); + let mut scheduler = core_scheduler(); let mut woken = 0; while woken != count || count == i32::MAX { match queue.get_mut().pop() { diff --git a/src/synch/recmutex.rs b/src/synch/recmutex.rs index 9491124e84..03520a97f5 100644 --- a/src/synch/recmutex.rs +++ b/src/synch/recmutex.rs @@ -27,10 +27,10 @@ impl RecursiveMutex { pub fn acquire(&self) { // Get information about the current task. - let core_scheduler = core_scheduler(); - let tid = core_scheduler.get_current_task_id(); + let tid = core_scheduler().get_current_task_id(); loop { + let mut core_scheduler = core_scheduler(); { let mut locked_state = self.state.lock(); diff --git a/src/synch/semaphore.rs b/src/synch/semaphore.rs index 1c508fb8a0..b0bb5558d9 100644 --- a/src/synch/semaphore.rs +++ b/src/synch/semaphore.rs @@ -68,12 +68,12 @@ impl Semaphore { pub fn acquire(&self, time: Option) -> bool { #[cfg(feature = "smp")] let backoff = Backoff::new(); - let core_scheduler = core_scheduler(); let wakeup_time = time.map(|ms| crate::arch::processor::get_timer_ticks() + ms * 1000); // Loop until we have acquired the semaphore. loop { + let mut core_scheduler = core_scheduler(); let mut locked_state = self.state.lock(); if locked_state.count > 0 { diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index e4962dae15..3edc6a8204 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -116,7 +116,7 @@ pub(crate) extern "C" fn __sys_usleep(usecs: u64) { // Enough time to set a wakeup timer and block the current task. debug!("sys_usleep blocking the task for {} microseconds", usecs); let wakeup_time = arch::processor::get_timer_ticks() + usecs; - let core_scheduler = core_scheduler(); + let mut core_scheduler = core_scheduler(); core_scheduler.block_current_task(Some(wakeup_time)); // Switch to the next task. @@ -300,7 +300,7 @@ static BLOCKED_TASKS: InterruptTicketMutex> = extern "C" fn __sys_block_current_task(timeout: &Option) { let wakeup_time = timeout.map(|t| arch::processor::get_timer_ticks() + t * 1000); - let core_scheduler = core_scheduler(); + let mut core_scheduler = core_scheduler(); let handle = core_scheduler.get_current_task_handle(); let tid = core_scheduler.get_current_task_id(); From 54503b70401f6b9d99f0a276b29d1af9c6b46166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 6 Oct 2023 10:53:28 +0200 Subject: [PATCH 2/2] WIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- Cargo.lock | 8 +++++ Cargo.toml | 1 + src/arch/aarch64/kernel/core_local.rs | 14 ++++++--- src/arch/aarch64/kernel/interrupts.rs | 45 ++++++++++++++++++++++----- src/arch/x86_64/kernel/core_local.rs | 14 ++++++--- src/arch/x86_64/kernel/scheduler.rs | 19 ++++++++++- src/scheduler/mod.rs | 10 +++--- src/scheduler/task.rs | 11 ++----- 8 files changed, 91 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed5cbcbe25..7b224c48cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -451,6 +451,7 @@ dependencies = [ "hermit-dtb", "hermit-entry", "hermit-sync", + "interrupt-ref-cell", "llvm-tools", "lock_api", "log", @@ -497,6 +498,13 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "interrupt-ref-cell" +version = "0.1.0" +dependencies = [ + "interrupts", +] + [[package]] name = "interrupts" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0891f453b4..14c674ce45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,7 @@ dyn-clone = "1.0" hashbrown = { version = "0.14", default-features = false } hermit-entry = { version = "0.9", features = ["kernel"] } hermit-sync = "0.1" +interrupt-ref-cell = { path = "../../interrupt-ref-cell" } lock_api = "0.4" log = { version = "0.4", default-features = false } num = { version = "0.4", default-features = false } diff --git a/src/arch/aarch64/kernel/core_local.rs b/src/arch/aarch64/kernel/core_local.rs index 44d4dffede..67320e4534 100644 --- a/src/arch/aarch64/kernel/core_local.rs +++ b/src/arch/aarch64/kernel/core_local.rs @@ -1,5 +1,6 @@ use alloc::boxed::Box; use alloc::vec::Vec; +use interrupt_ref_cell::{InterruptRefCell, InterruptRefMut}; use core::arch::asm; use core::cell::{RefCell, RefMut}; use core::ptr; @@ -20,7 +21,7 @@ pub(crate) struct CoreLocal { /// ID of the current Core. core_id: CoreId, /// Scheduler of the current Core. - scheduler: RefCell>, + scheduler: InterruptRefCell>, /// Interface to the interrupt counters irq_statistics: &'static IrqStatistics, /// Queue of async tasks @@ -44,7 +45,7 @@ impl CoreLocal { let this = Self { this: ptr::null_mut(), core_id, - scheduler: RefCell::new(None), + scheduler: InterruptRefCell::new(None), irq_statistics, async_tasks: RefCell::new(Vec::new()), #[cfg(feature = "smp")] @@ -91,8 +92,13 @@ pub(crate) fn core_id() -> CoreId { } } -pub(crate) fn core_scheduler() -> RefMut<'static, PerCoreScheduler> { - RefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { +#[track_caller] +pub(crate) fn core_scheduler() -> InterruptRefMut<'static, PerCoreScheduler> { + println!("{}", core::panic::Location::caller()); + if CoreLocal::get().scheduler.try_borrow().is_err() { + println!("Oh no"); + } + InterruptRefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { scheduler.as_mut().unwrap() }) } diff --git a/src/arch/aarch64/kernel/interrupts.rs b/src/arch/aarch64/kernel/interrupts.rs index 591cc5a64b..c6c7330401 100644 --- a/src/arch/aarch64/kernel/interrupts.rs +++ b/src/arch/aarch64/kernel/interrupts.rs @@ -1,7 +1,8 @@ use alloc::collections::BTreeMap; use alloc::vec::Vec; use core::arch::asm; -use core::sync::atomic::{AtomicU64, Ordering}; +use core::ops::DerefMut; +use core::sync::atomic::{AtomicU64, Ordering, compiler_fence}; use aarch64::regs::*; use ahash::RandomState; @@ -118,7 +119,20 @@ pub(crate) extern "C" fn do_fiq(state: &State) -> *mut usize { } } - core_scheduler().handle_waiting_tasks(); + let mut network_wakeup_time = None; + + #[cfg(any(feature = "tcp", feature = "udp"))] + if let Some(mut guard) = crate::executor::network::NIC.try_lock() { + if let crate::executor::network::NetworkState::Initialized(nic) = guard.deref_mut() { + let now = crate::executor::network::now(); + nic.poll_common(now); + let time = crate::arch::processor::get_timer_ticks(); + network_wakeup_time = nic.poll_delay(now).map(|d| d.total_micros() + time); + } + } + + crate::executor::run(); + core_scheduler().handle_waiting_tasks(network_wakeup_time); GicV3::end_interrupt(irqid); @@ -154,9 +168,21 @@ pub(crate) extern "C" fn do_irq(state: &State) -> *mut usize { } } - core_scheduler().handle_waiting_tasks(); + let mut network_wakeup_time = None; + + #[cfg(any(feature = "tcp", feature = "udp"))] + if let Some(mut guard) = crate::executor::network::NIC.try_lock() { + if let crate::executor::network::NetworkState::Initialized(nic) = guard.deref_mut() { + let now = crate::executor::network::now(); + nic.poll_common(now); + let time = crate::arch::processor::get_timer_ticks(); + network_wakeup_time = nic.poll_delay(now).map(|d| d.total_micros() + time); + } + } + + crate::executor::run(); + core_scheduler().handle_waiting_tasks(network_wakeup_time); - GicV3::end_interrupt(irqid); if unsafe { reschedule @@ -164,10 +190,15 @@ pub(crate) extern "C" fn do_irq(state: &State) -> *mut usize { || vector == SGI_RESCHED.try_into().unwrap() } { // a timer interrupt may have caused unblocking of tasks - return core_scheduler() - .scheduler() - .unwrap_or(core::ptr::null_mut()); + // run background tasks + crate::executor::run(); + let ret = core_scheduler() + .scheduler(); + compiler_fence(Ordering::SeqCst); + GicV3::end_interrupt(irqid); + return ret.unwrap_or(core::ptr::null_mut()); } + GicV3::end_interrupt(irqid); } core::ptr::null_mut() diff --git a/src/arch/x86_64/kernel/core_local.rs b/src/arch/x86_64/kernel/core_local.rs index 50509a9e22..d5ceb631fe 100644 --- a/src/arch/x86_64/kernel/core_local.rs +++ b/src/arch/x86_64/kernel/core_local.rs @@ -1,5 +1,6 @@ use alloc::boxed::Box; use alloc::vec::Vec; +use interrupt_ref_cell::{InterruptRefCell, InterruptRefMut}; use core::arch::asm; use core::cell::{Cell, RefCell, RefMut}; use core::ptr; @@ -24,7 +25,7 @@ pub(crate) struct CoreLocal { /// Sequential ID of this CPU Core. core_id: CoreId, /// Scheduler for this CPU Core. - scheduler: RefCell>, + scheduler: InterruptRefCell>, /// Task State Segment (TSS) allocated for this CPU Core. pub tss: Cell<*mut TaskStateSegment>, /// start address of the kernel stack @@ -54,7 +55,7 @@ impl CoreLocal { let this = Self { this: ptr::null_mut(), core_id, - scheduler: RefCell::new(None), + scheduler: InterruptRefCell::new(None), tss: Cell::new(ptr::null_mut()), kernel_stack: Cell::new(0), irq_statistics, @@ -101,8 +102,13 @@ pub(crate) fn core_id() -> CoreId { } } -pub(crate) fn core_scheduler() -> RefMut<'static, PerCoreScheduler> { - RefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { +#[track_caller] +pub(crate) fn core_scheduler() -> InterruptRefMut<'static, PerCoreScheduler> { + println!("{}", core::panic::Location::caller()); + if CoreLocal::get().scheduler.try_borrow().is_err() { + println!("Oh no"); + } + InterruptRefMut::map(CoreLocal::get().scheduler.borrow_mut(), |scheduler| { scheduler.as_mut().unwrap() }) } diff --git a/src/arch/x86_64/kernel/scheduler.rs b/src/arch/x86_64/kernel/scheduler.rs index 10fb48708b..76fd206593 100644 --- a/src/arch/x86_64/kernel/scheduler.rs +++ b/src/arch/x86_64/kernel/scheduler.rs @@ -2,6 +2,7 @@ use alloc::boxed::Box; use core::arch::asm; +use core::ops::DerefMut; use core::{mem, ptr, slice}; use align_address::Align; @@ -365,7 +366,23 @@ impl TaskFrame for Task { extern "x86-interrupt" fn timer_handler(_stack_frame: interrupts::ExceptionStackFrame) { increment_irq_counter(apic::TIMER_INTERRUPT_NUMBER); - core_scheduler().handle_waiting_tasks(); + + + let mut network_wakeup_time = None; + + #[cfg(any(feature = "tcp", feature = "udp"))] + if let Some(mut guard) = crate::executor::network::NIC.try_lock() { + if let crate::executor::network::NetworkState::Initialized(nic) = guard.deref_mut() { + let now = crate::executor::network::now(); + nic.poll_common(now); + let time = crate::arch::processor::get_timer_ticks(); + network_wakeup_time = nic.poll_delay(now).map(|d| d.total_micros() + time); + } + } + + crate::executor::run(); + + core_scheduler().handle_waiting_tasks(network_wakeup_time); apic::eoi(); core_scheduler().reschedule(); } diff --git a/src/scheduler/mod.rs b/src/scheduler/mod.rs index 53b75993e9..d26a7ce533 100644 --- a/src/scheduler/mod.rs +++ b/src/scheduler/mod.rs @@ -7,6 +7,7 @@ use core::sync::atomic::{AtomicU32, Ordering}; use crossbeam_utils::Backoff; use hermit_sync::{without_interrupts, *}; +use interrupt_ref_cell::{InterruptRefCell, InterruptRefMut}; use crate::arch; use crate::arch::core_local::*; @@ -87,7 +88,7 @@ pub trait PerCoreSchedulerExt { fn exit(self, exit_code: i32) -> !; } -impl PerCoreSchedulerExt for RefMut<'_, PerCoreScheduler> { +impl PerCoreSchedulerExt for InterruptRefMut<'_, PerCoreScheduler> { #[cfg(target_arch = "x86_64")] fn reschedule(mut self) { without_interrupts(|| { @@ -366,10 +367,9 @@ impl PerCoreScheduler { } #[inline] - pub fn handle_waiting_tasks(&mut self) { + pub fn handle_waiting_tasks(&mut self, network_wakeup_time: Option) { without_interrupts(|| { - crate::executor::run(); - for task in self.blocked_tasks.handle_waiting_tasks() { + for task in self.blocked_tasks.handle_waiting_tasks(network_wakeup_time) { self.ready_queue.push(task); } }); @@ -576,8 +576,6 @@ impl PerCoreScheduler { /// Triggers the scheduler to reschedule the tasks. /// Interrupt flag must be cleared before calling this function. pub fn scheduler(&mut self) -> Option<*mut usize> { - // run background tasks - crate::executor::run(); // Someone wants to give up the CPU // => we have time to cleanup the system diff --git a/src/scheduler/task.rs b/src/scheduler/task.rs index 7078e9a3f0..b06ea2f16f 100644 --- a/src/scheduler/task.rs +++ b/src/scheduler/task.rs @@ -622,18 +622,11 @@ 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) -> Vec>> { + pub fn handle_waiting_tasks(&mut self, network_time_delay: Option) -> Vec>> { // Get the current time. let time = arch::processor::get_timer_ticks(); - #[cfg(any(feature = "tcp", feature = "udp"))] - if let Some(mut guard) = crate::executor::network::NIC.try_lock() { - if let crate::executor::network::NetworkState::Initialized(nic) = guard.deref_mut() { - let now = crate::executor::network::now(); - nic.poll_common(now); - self.network_wakeup_time = nic.poll_delay(now).map(|d| d.total_micros() + time); - } - } + self.network_wakeup_time = network_time_delay; let mut tasks = vec![];