time/
manager.rs

1use crate::{Error, Result};
2use core::time::Duration;
3use file_system::DirectCharacterDevice;
4use synchronization::once_lock::OnceLock;
5
6pub static MANAGER: OnceLock<Manager> = OnceLock::new();
7
8pub fn get_instance() -> &'static Manager<'static> {
9    MANAGER.try_get().expect("Time manager is not initialized")
10}
11
12pub fn initialize(
13    driver: &'static (dyn DirectCharacterDevice + Send + Sync),
14) -> Result<&'static Manager<'static>> {
15    MANAGER.get_or_init(|| Manager::new(driver).expect("Failed to initialize time manager"));
16
17    Ok(get_instance())
18}
19
20pub struct Manager<'a> {
21    device: &'a (dyn DirectCharacterDevice + Send + Sync),
22    start_time: Duration,
23}
24
25impl<'a> Manager<'a> {
26    pub fn new(device: &'a (dyn DirectCharacterDevice + Send + Sync)) -> Result<Self> {
27        let start_time = Self::get_current_time_from_device(device)?;
28
29        Ok(Self { device, start_time })
30    }
31
32    pub fn get_current_time_since_startup(&self) -> Result<Duration> {
33        let current_time = self.get_current_time()?;
34
35        Ok(current_time.abs_diff(self.start_time))
36    }
37
38    pub fn get_current_time(&self) -> Result<Duration> {
39        Self::get_current_time_from_device(self.device)
40    }
41
42    fn get_current_time_from_device(device: &dyn DirectCharacterDevice) -> Result<Duration> {
43        let mut current_time = Duration::default();
44
45        let current_time_raw = unsafe {
46            core::slice::from_raw_parts_mut(
47                &mut current_time as *mut Duration as *mut u8,
48                core::mem::size_of::<Duration>(),
49            )
50        };
51
52        device
53            .read(current_time_raw, 0)
54            .map_err(Error::DeviceError)?;
55
56        Ok(current_time)
57    }
58}