- Vendor coarsetime crate with portable-atomic fallback - Use portable-atomic on targets without 64-bit atomics - Patch crates.io to use local coarsetime - Fixes MIPS build failure (AtomicU64 missing)
94 lines
2.4 KiB
Rust
94 lines
2.4 KiB
Rust
#[cfg(not(all(
|
|
any(target_arch = "wasm32", target_arch = "wasm64"),
|
|
target_os = "unknown"
|
|
)))]
|
|
use std::time;
|
|
|
|
#[cfg(target_has_atomic = "64")]
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
#[cfg(not(target_has_atomic = "64"))]
|
|
use portable_atomic::{AtomicU64, Ordering};
|
|
|
|
use super::Duration;
|
|
|
|
static RECENT: AtomicU64 = AtomicU64::new(0);
|
|
|
|
#[cfg(all(
|
|
any(target_arch = "wasm32", target_arch = "wasm64"),
|
|
target_os = "unknown"
|
|
))]
|
|
mod js_imports {
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
#[wasm_bindgen]
|
|
extern "C" {
|
|
pub type Date;
|
|
|
|
#[wasm_bindgen(static_method_of = Date)]
|
|
pub fn now() -> f64;
|
|
}
|
|
}
|
|
|
|
/// System time
|
|
#[derive(Debug)]
|
|
pub struct Clock;
|
|
|
|
/// Alias for `Duration`.
|
|
pub type UnixTimeStamp = Duration;
|
|
|
|
impl Clock {
|
|
/// Returns the elapsed time since the UNIX epoch
|
|
#[inline]
|
|
pub fn now_since_epoch() -> UnixTimeStamp {
|
|
Duration::from_u64(unix_ts())
|
|
}
|
|
|
|
/// Returns the elapsed time since the UNIX epoch, based on the latest
|
|
/// explicit time update
|
|
#[inline]
|
|
pub fn recent_since_epoch() -> UnixTimeStamp {
|
|
Duration::from_u64(RECENT.load(Ordering::Relaxed))
|
|
}
|
|
|
|
/// Updates the cached system time.
|
|
///
|
|
/// This function should be called frequently, for example in an event loop
|
|
/// or using an `Updater` task.
|
|
#[inline]
|
|
pub fn update() {
|
|
let now = unix_ts();
|
|
RECENT.store(now, Ordering::Relaxed)
|
|
}
|
|
|
|
/// Sets the cached system time to the specified timestamp.
|
|
/// This function is intended for testing purposes only.
|
|
/// It should not be used in production code.
|
|
pub fn set_recent_since_epoch(recent: UnixTimeStamp) {
|
|
RECENT.store(recent.as_u64(), Ordering::Relaxed)
|
|
}
|
|
}
|
|
|
|
#[cfg(all(
|
|
any(target_arch = "wasm32", target_arch = "wasm64"),
|
|
target_os = "unknown"
|
|
))]
|
|
#[inline]
|
|
fn unix_ts() -> u64 {
|
|
let unix_ts_now_sys = (js_imports::Date::now() / 1000.0).round() as u64;
|
|
let unix_ts_now = Duration::from_secs(unix_ts_now_sys);
|
|
unix_ts_now.as_u64()
|
|
}
|
|
|
|
#[cfg(not(all(
|
|
any(target_arch = "wasm32", target_arch = "wasm64"),
|
|
target_os = "unknown"
|
|
)))]
|
|
#[inline]
|
|
fn unix_ts() -> u64 {
|
|
let unix_ts_now_sys = time::SystemTime::now()
|
|
.duration_since(time::UNIX_EPOCH)
|
|
.expect("The system clock is not properly set");
|
|
let unix_ts_now = Duration::from(unix_ts_now_sys);
|
|
unix_ts_now.as_u64()
|
|
}
|