Skip to main content

osiris/
time.rs

1use crate::hal::{self, Machinelike};
2
3use crate::{sched, sync};
4
5static TICKS: sync::atomic::AtomicU64 = sync::atomic::AtomicU64::new(0);
6
7pub fn tick() -> u64 {
8    TICKS.load(sync::atomic::Ordering::Acquire)
9}
10
11pub fn mono_now() -> u64 {
12    // TODO: This will break on SMP systems without native u64 atomic store.
13    sync::atomic::irq_free(|| hal::Machine::monotonic_now())
14}
15
16pub fn mono_freq() -> u64 {
17    hal::Machine::monotonic_freq()
18}
19
20pub fn to_secs(cnt: u64, hz: u32, digits: u8) -> (u64, u64) {
21    let secs = cnt / (hz as u64);
22    let rem = cnt % (hz as u64);
23    let frac = (rem * 10_u64.pow(digits as u32)) / (hz as u64);
24    (secs, frac)
25}
26
27/// cbindgen:ignore
28/// cbindgen:no-export
29#[unsafe(no_mangle)]
30pub extern "C" fn systick_hndlr() {
31    let tick = TICKS.fetch_add(1, sync::atomic::Ordering::Release) + 1;
32
33    sync::atomic::irq_free(|| {
34        hal::Machine::do_tick();
35    });
36
37    if sched::needs_reschedule(tick) {
38        sched::reschedule();
39    }
40}