kernel/
time.rs

1use crate::{sched, sync::spinlock::SpinLocked};
2use hal::Schedable;
3
4// This variable is only allowed to be modified by the systick handler.
5static TIME: SpinLocked<u64> = SpinLocked::new(0);
6
7fn tick() {
8    // Increment the global time counter.
9    {
10        let mut time = TIME.lock();
11        *time += 1;
12    }
13}
14
15/*
16 * Returns the current time in milliseconds after boot.
17 *
18 */
19pub fn time() -> u64 {
20    if !hal::asm::are_interrupts_enabled() {
21        // If interrupts are disabled, we can just read the time.
22        return *TIME.lock();
23    } else {
24        let time;
25        // We need to disable interrupts to ensure that systick is always able to lock the time.
26        hal::asm::disable_interrupts();
27        // Return the current time.
28        {
29            time = *TIME.lock();
30        }
31        hal::asm::enable_interrupts();
32        // Now systick can be called again.
33        time
34    }
35}
36
37/// cbindgen:ignore
38/// cbindgen:no-export
39#[unsafe(no_mangle)]
40pub extern "C" fn systick_hndlr() {
41    tick();
42
43    let resched = { sched::tick_scheduler() };
44
45    if resched {
46        hal::Machine::trigger_reschedule();
47    }
48}