1use core::sync::atomic::{AtomicUsize, Ordering};
5
6use crate::{arch::lib::sbi::set_timer, kernel::CLOCK_FREQ};
7use riscv::register::time;
8
9pub const TICKS_PER_SEC: usize = 100;
12pub const MSEC_PER_SEC: usize = 1000;
14
15pub static TIMER_TICKS: AtomicUsize = AtomicUsize::new(0);
17
18#[inline]
20pub fn get_ticks() -> usize {
21 TIMER_TICKS.load(Ordering::Relaxed)
22}
23
24#[inline]
26pub fn get_time() -> usize {
27 time::read()
28}
29
30#[inline]
32pub fn get_time_ms() -> usize {
33 (time::read() as u128 * MSEC_PER_SEC as u128 / clock_freq() as u128) as usize
34}
35
36#[inline]
38pub fn set_next_trigger() {
39 let next = get_time() + clock_freq() / TICKS_PER_SEC;
40 set_timer(next);
41}
42
43pub fn init() {
45 set_next_trigger();
46 unsafe { crate::arch::intr::enable_timer_interrupt() };
48}
49
50#[inline]
52pub fn clock_freq() -> usize {
53 unsafe { CLOCK_FREQ }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::{kassert, println, test_case};
61 test_case!(test_set_next_trigger, {
62 let current_time = get_time();
63 set_next_trigger();
64 let next_time = get_time();
65 kassert!(next_time > current_time);
66 });
67
68 test_case!(test_get_time, {
91 println!("Testing get_time...");
92 let time = get_time();
93 kassert!(time > 0);
94 });
95
96 test_case!(test_get_time_ms, {
97 println!("Testing get_time_ms...");
98 let time_ms = get_time_ms();
99 kassert!(time_ms > 0);
100 });
101}