mod.rs 890 B

123456789101112131415161718192021222324252627282930313233
  1. use core::time::Duration;
  2. use super::timer::{Instant, Ticks};
  3. use alloc::sync::Arc;
  4. use eonix_log::println_warn;
  5. use eonix_sync::Spin;
  6. static RTC: Spin<Option<Arc<dyn RealTimeClock>>> = Spin::new(None);
  7. pub trait RealTimeClock: Send + Sync {
  8. fn now(&self) -> Instant;
  9. }
  10. impl Instant {
  11. pub fn now() -> Instant {
  12. RTC.lock().as_ref().map(|rtc| rtc.now()).unwrap_or_else(|| {
  13. let since_boot = Ticks::since_boot();
  14. let pseudo_now = Duration::from_secs((55 * 365 + 30) * 24 * 3600) + since_boot;
  15. Instant::new(pseudo_now.as_secs(), pseudo_now.subsec_nanos())
  16. })
  17. }
  18. }
  19. pub fn register_rtc(rtc: impl RealTimeClock + 'static) {
  20. let mut rtc_lock = RTC.lock();
  21. if rtc_lock.is_some() {
  22. println_warn!("RTC is already registered, ignoring new registration");
  23. return;
  24. }
  25. *rtc_lock = Some(Arc::new(rtc));
  26. }