2024-12-10 11:52:26 +02:00
|
|
|
use core::sync::atomic::{AtomicU64, Ordering};
|
|
|
|
|
|
|
|
use yggdrasil_abi::time::SystemTime;
|
|
|
|
|
2024-12-10 12:17:52 +02:00
|
|
|
// Millisecond resolution
|
|
|
|
const NANOSECONDS_IN_SECOND: u64 = 1_000_000_000;
|
|
|
|
const TIME_RESOLUTION_NS: u64 = 1_000_000;
|
|
|
|
pub const TICKS_PER_SEC: u64 = NANOSECONDS_IN_SECOND / TIME_RESOLUTION_NS;
|
2024-12-10 11:52:26 +02:00
|
|
|
|
2024-12-10 12:17:52 +02:00
|
|
|
static MONOTONIC_TIME: AtomicU64 = AtomicU64::new(0);
|
|
|
|
static REAL_TIME_OFFSET: AtomicU64 = AtomicU64::new(0);
|
|
|
|
static REAL_TIME: AtomicU64 = AtomicU64::new(0);
|
2024-12-10 11:52:26 +02:00
|
|
|
|
2024-12-10 12:17:52 +02:00
|
|
|
#[inline]
|
|
|
|
fn make_time(ticks: u64) -> SystemTime {
|
2024-12-10 11:52:26 +02:00
|
|
|
SystemTime {
|
2024-12-10 12:17:52 +02:00
|
|
|
seconds: ticks / TICKS_PER_SEC,
|
|
|
|
nanoseconds: (ticks % TICKS_PER_SEC) * TIME_RESOLUTION_NS,
|
2024-12-10 11:52:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-10 12:17:52 +02:00
|
|
|
pub fn real_time() -> SystemTime {
|
|
|
|
make_time(REAL_TIME.load(Ordering::Acquire) + REAL_TIME_OFFSET.load(Ordering::Relaxed))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn monotonic_time() -> SystemTime {
|
|
|
|
make_time(MONOTONIC_TIME.load(Ordering::Acquire))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_ticks(ticks: u64) {
|
|
|
|
MONOTONIC_TIME.fetch_add(ticks, Ordering::Release);
|
|
|
|
REAL_TIME_OFFSET.fetch_add(ticks, Ordering::Release);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_real_time(ticks: u64, reset: bool) {
|
|
|
|
REAL_TIME.store(ticks, Ordering::Release);
|
|
|
|
if reset {
|
|
|
|
REAL_TIME_OFFSET.store(0, Ordering::Release);
|
|
|
|
}
|
2024-12-10 11:52:26 +02:00
|
|
|
}
|
|
|
|
|
2024-12-10 12:17:52 +02:00
|
|
|
pub fn set_ticks(ticks: u64) {
|
|
|
|
MONOTONIC_TIME.store(ticks, Ordering::Release);
|
|
|
|
REAL_TIME_OFFSET.store(ticks, Ordering::Release);
|
2024-12-10 11:52:26 +02:00
|
|
|
}
|