46 lines
1.3 KiB
Rust
Raw Normal View History

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 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 12:17:52 +02:00
#[inline]
fn make_time(ticks: u64) -> SystemTime {
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 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 12:17:52 +02:00
pub fn set_ticks(ticks: u64) {
MONOTONIC_TIME.store(ticks, Ordering::Release);
REAL_TIME_OFFSET.store(ticks, Ordering::Release);
}