1mod jiffies;
6
7use alloc::{boxed::Box, vec::Vec};
8use core::{cell::RefCell, sync::atomic::Ordering};
9
10pub use jiffies::Jiffies;
11
12use crate::{
13 arch::trap::TrapFrame,
14 cpu::{CpuId, PinCurrentCpu},
15 cpu_local, irq,
16};
17
18pub const TIMER_FREQ: u64 = 1000;
26
27type InterruptCallback = Box<dyn Fn() + Sync + Send>;
28
29cpu_local! {
30 static INTERRUPT_CALLBACKS: RefCell<Vec<InterruptCallback>> = RefCell::new(Vec::new());
31}
32
33pub fn register_callback_on_cpu<F>(func: F)
35where
36 F: Fn() + Sync + Send + 'static,
37{
38 let irq_guard = irq::disable_local();
39 INTERRUPT_CALLBACKS
40 .get_with(&irq_guard)
41 .borrow_mut()
42 .push(Box::new(func));
43}
44
45pub(crate) fn call_timer_callback_functions(_: &TrapFrame) {
46 let irq_guard = irq::disable_local();
47
48 if irq_guard.current_cpu() == CpuId::bsp() {
49 jiffies::ELAPSED.fetch_add(1, Ordering::Relaxed);
50 }
51
52 let callbacks_guard = INTERRUPT_CALLBACKS.get_with(&irq_guard);
53 for callback in callbacks_guard.borrow().iter() {
54 (callback)();
55 }
56 drop(callbacks_guard);
57}