Skip to main content

hermit/
time.rs

1use core::time::Duration;
2
3use crate::arch::kernel::systemtime;
4
5#[allow(non_camel_case_types)]
6pub type time_t = i64;
7#[allow(non_camel_case_types)]
8pub type useconds_t = u32;
9#[allow(non_camel_case_types)]
10pub type suseconds_t = i32;
11
12/// Represent the number of seconds and microseconds since
13/// the Epoch (1970-01-01 00:00:00 +0000 (UTC))
14#[derive(Copy, Clone, Debug)]
15#[repr(C)]
16pub struct timeval {
17	/// Seconds
18	pub tv_sec: time_t,
19	/// Microseconds
20	pub tv_usec: suseconds_t,
21}
22
23impl timeval {
24	pub fn from_usec(microseconds: i64) -> Self {
25		Self {
26			tv_sec: (microseconds / 1_000_000),
27			tv_usec: (microseconds % 1_000_000) as i32,
28		}
29	}
30
31	pub fn into_usec(&self) -> Option<i64> {
32		self.tv_sec
33			.checked_mul(1_000_000)
34			.and_then(|usec| usec.checked_add(self.tv_usec.into()))
35	}
36}
37
38/// Represent the timer interval in seconds and microseconds
39#[derive(Copy, Clone, Debug)]
40#[repr(C)]
41pub struct itimerval {
42	pub it_interval: timeval,
43	pub it_value: timeval,
44}
45
46/// Represent the number of seconds and nanoseconds since
47/// the Epoch (1970-01-01 00:00:00 +0000 (UTC))
48#[derive(Copy, Clone, Debug, Default)]
49#[repr(C)]
50pub struct timespec {
51	/// Seconds
52	pub tv_sec: time_t,
53	/// Nanoseconds
54	pub tv_nsec: i32,
55}
56
57impl timespec {
58	pub fn from_usec(microseconds: i64) -> Self {
59		Self {
60			tv_sec: (microseconds / 1_000_000),
61			tv_nsec: ((microseconds % 1_000_000) * 1000) as i32,
62		}
63	}
64
65	pub fn into_usec(&self) -> Option<i64> {
66		self.tv_sec
67			.checked_mul(1_000_000)
68			.and_then(|usec| usec.checked_add((self.tv_nsec / 1000).into()))
69	}
70}
71
72#[derive(Copy, Clone, Debug, Default)]
73pub struct SystemTime(timespec);
74
75impl SystemTime {
76	pub const UNIX_EPOCH: SystemTime = Self(timespec {
77		tv_sec: 0,
78		tv_nsec: 0,
79	});
80
81	/// Returns the system time corresponding to "now".
82	pub fn now() -> Self {
83		Self(timespec::from_usec(systemtime::now_micros() as i64))
84	}
85
86	/// Returns the amount of time elapsed from an earlier point in time.
87	pub fn duration_since(&self, earlier: SystemTime) -> Duration {
88		Duration::from_micros(
89			self.0
90				.into_usec()
91				.unwrap()
92				.checked_sub(earlier.0.into_usec().unwrap())
93				.unwrap()
94				.try_into()
95				.unwrap(),
96		)
97	}
98}
99
100impl From<timespec> for SystemTime {
101	fn from(t: timespec) -> Self {
102		Self(t)
103	}
104}
105
106impl From<SystemTime> for timespec {
107	fn from(value: SystemTime) -> Self {
108		value.0
109	}
110}