use alloc::sync::Arc;
use core::{
sync::atomic::{AtomicU64, Ordering},
time::Duration,
};
use crate::{
irq::irqflags::{local_irq_restore, local_irq_save},
processor::this_processor_id,
time::{
hrtimer::{Hrtimer, HrtimerMode, HrtimerRestart, hrtimer_start},
timekeeping::update_wall_time,
},
};
const SYSTEM_TICK_MS: u64 = 5;
static JIFFIES: AtomicU64 = AtomicU64::new(0);
static PERIODIC_NS: AtomicU64 = AtomicU64::new(0);
pub fn jiffies() -> u64 {
JIFFIES.load(Ordering::Relaxed)
}
fn tick_periodic(timer: &Hrtimer) -> HrtimerRestart {
if this_processor_id() == 0 {
JIFFIES.fetch_add(1, Ordering::Relaxed);
update_wall_time();
}
let periodic_ns = PERIODIC_NS.load(Ordering::Relaxed);
timer.forward_now(periodic_ns);
HrtimerRestart::Restart
}
#[allow(clippy::similar_names)]
pub(super) fn system_tick_init_cpu() {
let periodic_ms = SYSTEM_TICK_MS;
let periodic_ns = Duration::from_millis(periodic_ms).as_nanos() as u64;
let flags = local_irq_save();
let timer = Hrtimer::create(HrtimerMode::Rel, tick_periodic, None);
PERIODIC_NS.store(periodic_ns, Ordering::Relaxed);
hrtimer_start(&Arc::new(timer), periodic_ns);
local_irq_restore(flags);
}