mod jiffies;
use alloc::{boxed::Box, vec::Vec};
use core::{cell::RefCell, sync::atomic::Ordering};
pub use jiffies::Jiffies;
use crate::{
arch::trap::TrapFrame,
cpu::{CpuId, PinCurrentCpu},
cpu_local, irq,
};
pub const TIMER_FREQ: u64 = 1000;
type InterruptCallback = Box<dyn Fn() + Sync + Send>;
cpu_local! {
static INTERRUPT_CALLBACKS: RefCell<Vec<InterruptCallback>> = RefCell::new(Vec::new());
}
pub fn register_callback_on_cpu<F>(func: F)
where
F: Fn() + Sync + Send + 'static,
{
let irq_guard = irq::disable_local();
INTERRUPT_CALLBACKS
.get_with(&irq_guard)
.borrow_mut()
.push(Box::new(func));
}
pub(crate) fn call_timer_callback_functions(_: &TrapFrame) {
let irq_guard = irq::disable_local();
if irq_guard.current_cpu() == CpuId::bsp() {
jiffies::ELAPSED.fetch_add(1, Ordering::Relaxed);
}
let callbacks_guard = INTERRUPT_CALLBACKS.get_with(&irq_guard);
for callback in callbacks_guard.borrow().iter() {
(callback)();
}
drop(callbacks_guard);
}