Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <[email protected]>
  • Loading branch information
mkroening committed Oct 6, 2023
1 parent af32258 commit 54503b7
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 31 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
14 changes: 10 additions & 4 deletions src/arch/aarch64/kernel/core_local.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -20,7 +21,7 @@ pub(crate) struct CoreLocal {
/// ID of the current Core.
core_id: CoreId,
/// Scheduler of the current Core.
scheduler: RefCell<Option<PerCoreScheduler>>,
scheduler: InterruptRefCell<Option<PerCoreScheduler>>,
/// Interface to the interrupt counters
irq_statistics: &'static IrqStatistics,
/// Queue of async tasks
Expand All @@ -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")]
Expand Down Expand Up @@ -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()
})
}
Expand Down
45 changes: 38 additions & 7 deletions src/arch/aarch64/kernel/interrupts.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -154,20 +168,37 @@ 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
|| vector == TIMER_INTERRUPT.try_into().unwrap()
|| 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()
Expand Down
14 changes: 10 additions & 4 deletions src/arch/x86_64/kernel/core_local.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -24,7 +25,7 @@ pub(crate) struct CoreLocal {
/// Sequential ID of this CPU Core.
core_id: CoreId,
/// Scheduler for this CPU Core.
scheduler: RefCell<Option<PerCoreScheduler>>,
scheduler: InterruptRefCell<Option<PerCoreScheduler>>,
/// Task State Segment (TSS) allocated for this CPU Core.
pub tss: Cell<*mut TaskStateSegment>,
/// start address of the kernel stack
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()
})
}
Expand Down
19 changes: 18 additions & 1 deletion src/arch/x86_64/kernel/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down
10 changes: 4 additions & 6 deletions src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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(|| {
Expand Down Expand Up @@ -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<u64>) {
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);
}
});
Expand Down Expand Up @@ -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
Expand Down
11 changes: 2 additions & 9 deletions src/scheduler/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Rc<RefCell<Task>>> {
pub fn handle_waiting_tasks(&mut self, network_time_delay: Option<u64>) -> Vec<Rc<RefCell<Task>>> {
// 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![];

Expand Down

0 comments on commit 54503b7

Please sign in to comment.