feat(kernel): WatchDeath + SetTimer events as notification signals; adapter wakes at earliest deadline
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use crate::board;
|
||||
use crate::smp::{MAX_HARTS, hart_id};
|
||||
|
||||
/// When each hart's timer is set to go off next.
|
||||
static NEXT: [AtomicU64; MAX_HARTS] = [const { AtomicU64::new(u64::MAX) }; MAX_HARTS];
|
||||
|
||||
pub fn read_time() -> u64 {
|
||||
let time: u64;
|
||||
@@ -21,15 +27,27 @@ fn sbi_set_timer(stime: u64) {
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let now = read_time();
|
||||
sbi_set_timer(now + board::TICK_INTERVAL);
|
||||
set_next(read_time() + board::TICK_INTERVAL);
|
||||
}
|
||||
|
||||
pub fn set_next(deadline: u64) {
|
||||
if let Some(next) = NEXT.get(hart_id()) {
|
||||
next.store(deadline, Ordering::Relaxed);
|
||||
}
|
||||
sbi_set_timer(deadline);
|
||||
}
|
||||
|
||||
pub fn handle_interrupt() {
|
||||
let now = read_time();
|
||||
sbi_set_timer(now + board::TICK_INTERVAL);
|
||||
/// Goes off at `deadline` too, if that is before the next tick.
|
||||
pub fn wake_at(deadline: u64) {
|
||||
if NEXT
|
||||
.get(hart_id())
|
||||
.is_some_and(|n| deadline < n.load(Ordering::Relaxed))
|
||||
{
|
||||
set_next(deadline);
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-arms the tick; the kernel then re-arms for its earliest timer.
|
||||
pub fn handle_interrupt() {
|
||||
set_next(read_time() + board::TICK_INTERVAL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user