-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
Adds windows support to clocksource
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,5 @@ | |
pub mod coarse; | ||
pub mod datetime; | ||
pub mod precise; | ||
|
||
mod sys; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#[cfg(not(target_os = "windows"))] | ||
mod unix; | ||
#[cfg(not(target_os = "windows"))] | ||
pub use unix::*; | ||
|
||
#[cfg(target_os = "windows")] | ||
mod windows; | ||
#[cfg(target_os = "windows")] | ||
pub use windows::*; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#[cfg(any(target_os = "macos", target_os = "ios"))] | ||
const CLOCK_MONOTONIC_COARSE: u32 = libc::CLOCK_MONOTONIC; | ||
|
||
#[cfg(not(any(target_os = "macos", target_os = "ios")))] | ||
const CLOCK_MONOTONIC_COARSE: u32 = libc::CLOCK_MONOTONIC_COARSE; | ||
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
|
||
|
||
#[cfg(any(target_os = "macos", target_os = "ios"))] | ||
const CLOCK_REALTIME_COARSE: u32 = libc::CLOCK_REALTIME; | ||
|
||
#[cfg(not(any(target_os = "macos", target_os = "ios")))] | ||
const CLOCK_REALTIME_COARSE: u32 = libc::CLOCK_REALTIME_COARSE; | ||
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
|
||
|
||
pub fn read_clock(clock: u32) -> libc::timespec { | ||
let mut ts = libc::timespec { | ||
tv_sec: 0, | ||
tv_nsec: 0, | ||
}; | ||
|
||
unsafe { | ||
libc::clock_gettime(clock, &mut ts); | ||
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
|
||
} | ||
|
||
ts | ||
} | ||
|
||
pub mod monotonic { | ||
use super::*; | ||
|
||
pub fn coarse() -> crate::coarse::Instant { | ||
let ts = read_clock(CLOCK_MONOTONIC_COARSE); | ||
|
||
let now = ts.tv_sec as u32; | ||
|
||
crate::coarse::Instant { secs: now } | ||
} | ||
|
||
pub fn precise() -> crate::precise::Instant { | ||
let ts = read_clock(libc::CLOCK_MONOTONIC); | ||
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
|
||
|
||
let now = (ts.tv_sec as u64) | ||
.wrapping_mul(1_000_000_000) | ||
.wrapping_add(ts.tv_nsec as u64); | ||
|
||
crate::precise::Instant { ns: now } | ||
} | ||
} | ||
|
||
pub mod realtime { | ||
use super::*; | ||
|
||
pub fn coarse() -> crate::coarse::UnixInstant { | ||
let ts = read_clock(CLOCK_REALTIME_COARSE); | ||
|
||
let now = ts.tv_sec as u32; | ||
|
||
crate::coarse::UnixInstant { secs: now } | ||
} | ||
|
||
pub fn precise() -> crate::precise::UnixInstant { | ||
let ts = read_clock(libc::CLOCK_REALTIME); | ||
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
Check failure Code scanning / clippy mismatched types Error
mismatched types
|
||
|
||
let now = (ts.tv_sec as u64) | ||
.wrapping_mul(1_000_000_000) | ||
.wrapping_add(ts.tv_nsec as u64); | ||
|
||
crate::precise::UnixInstant { ns: now } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use core::sync::atomic::{AtomicU64, Ordering}; | ||
|
||
const NANOS_PER_SEC: u64 = 1_000_000_000; | ||
|
||
pub mod monotonic { | ||
use super::*; | ||
|
||
use winapi::um::winnt::LARGE_INTEGER; | ||
|
||
static FREQUENCY: AtomicU64 = AtomicU64::new(0); | ||
|
||
fn frequency() -> u64 { | ||
let cached = FREQUENCY.load(Ordering::Relaxed); | ||
|
||
if cached != 0 { | ||
return cached; | ||
} | ||
|
||
let frequency; | ||
unsafe { | ||
let mut frq: LARGE_INTEGER = core::mem::zeroed(); | ||
let _ = winapi::um::profileapi::QueryPerformanceFrequency(&mut frq); | ||
frequency = *frq.QuadPart() as u64; | ||
} | ||
|
||
FREQUENCY.store(frequency, Ordering::Relaxed); | ||
frequency | ||
} | ||
|
||
fn count() -> u64 { | ||
unsafe { | ||
let mut cnt: LARGE_INTEGER = core::mem::zeroed(); | ||
let _ = winapi::um::profileapi::QueryPerformanceCounter(&mut cnt); | ||
*cnt.QuadPart() as u64 | ||
} | ||
} | ||
|
||
pub fn coarse() -> crate::coarse::Instant { | ||
let count = count(); | ||
let frequency = frequency(); | ||
|
||
let q = count / frequency; | ||
let r = count % frequency; | ||
|
||
crate::coarse::Instant { | ||
secs: (q + r / frequency) as u32 | ||
} | ||
} | ||
|
||
pub fn precise() -> crate::precise::Instant { | ||
let count = count(); | ||
let frequency = frequency(); | ||
|
||
let q = count / frequency; | ||
let r = count % frequency; | ||
|
||
crate::precise::Instant { | ||
ns: q * NANOS_PER_SEC + r * NANOS_PER_SEC / frequency | ||
} | ||
} | ||
} | ||
|
||
pub mod realtime { | ||
use super::*; | ||
|
||
use winapi::shared::minwindef::FILETIME; | ||
|
||
const UNIX_EPOCH_INTERVALS: u64 = 116_444_736 * NANOS_PER_SEC; | ||
const NANOS_PER_INTERVAL: u64 = 100; | ||
|
||
const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / NANOS_PER_INTERVAL; | ||
|
||
fn unix_intervals() -> u64 { | ||
let filetime; | ||
unsafe { | ||
let mut ft: FILETIME = core::mem::zeroed(); | ||
let _ = winapi::um::sysinfoapi::GetSystemTimePreciseAsFileTime(&mut ft); | ||
filetime = (core::mem::transmute::<FILETIME, i64>(ft)) as u64; | ||
} | ||
|
||
filetime - UNIX_EPOCH_INTERVALS | ||
} | ||
|
||
pub fn coarse() -> crate::coarse::UnixInstant { | ||
crate::coarse::UnixInstant { | ||
secs: (unix_intervals() / INTERVALS_PER_SEC) as u32 | ||
} | ||
} | ||
|
||
pub fn precise() -> crate::precise::UnixInstant { | ||
crate::precise::UnixInstant { | ||
ns: unix_intervals() * NANOS_PER_INTERVAL | ||
} | ||
} | ||
} |