diff --git a/Cargo.toml b/Cargo.toml index a95b419..cdfad14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,16 +16,11 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] ctor = "0.1.20" +coarsetime = "0.1" [features] atomic = [] -[target.'cfg(not(target_os = "wasi"))'.dependencies] -libc = "0.2" - -[target.'cfg(target_os = "wasi")'.dependencies] -wasi = "0.7" - [dev-dependencies] criterion = "0.3" quanta = "0.9" diff --git a/src/coarse_now.rs b/src/coarse_now.rs deleted file mode 100644 index ed1d5c1..0000000 --- a/src/coarse_now.rs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0. - -//! Get instant value in nanosecond unit as fast as possible but less precise. - -#[allow(unused_imports)] -use std::mem::MaybeUninit; - -#[cfg(windows)] -extern "system" { - pub fn GetTickCount() -> libc::c_ulong; -} - -#[cfg(any(target_os = "macos", target_os = "freebsd"))] -#[allow(non_camel_case_types)] -type clockid_t = libc::c_int; - -#[cfg(target_os = "macos")] -const CLOCK_MONOTONIC_RAW_APPROX: clockid_t = 5; - -#[cfg(target_os = "macos")] -extern "system" { - pub fn clock_gettime_nsec_np(clk_id: clockid_t) -> u64; -} - -#[cfg(target_os = "freebsd")] -const CLOCK_MONOTONIC_FAST: clockid_t = 12; - -#[cfg(any(target_os = "linux", target_os = "android"))] -#[inline] -pub(crate) fn current_cycle() -> u64 { - let mut tp = MaybeUninit::::uninit(); - let tp = unsafe { - libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()); - tp.assume_init() - }; - tp.tv_sec as u64 * 1_000_000_000 + tp.tv_nsec as u64 -} - -#[cfg(target_os = "macos")] -#[inline] -pub(crate) fn current_cycle() -> u64 { - unsafe { clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW_APPROX) } -} - -#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] -#[inline] -pub(crate) fn current_cycle() -> u64 { - let mut tp = MaybeUninit::::uninit(); - let tp = unsafe { - libc::clock_gettime(libc::CLOCK_MONOTONIC_FAST, tp.as_mut_ptr()); - tp.assume_init() - }; - tp.tv_sec as u64 * 1_000_000_000 + tp.tv_nsec as u64 -} - -#[cfg(all( - unix, - not(any( - target_os = "macos", - target_os = "linux", - target_os = "android", - target_os = "freebsd", - target_os = "dragonfly" - )) -))] -#[inline] -pub(crate) fn current_cycle() -> u64 { - let mut tv = MaybeUninit::::uninit(); - let tv = unsafe { - libc::gettimeofday(tv.as_mut_ptr(), null_mut()); - tv.assume_init() - }; - tv.tv_sec as u64 * 1_000_000_000 + tv.tv_usec as u64 * 1_000 -} - -#[cfg(windows)] -#[inline] -pub(crate) fn current_cycle() -> u64 { - let millis = unsafe { GetTickCount() } as u64; - millis * 1_000_000 -} - -#[cfg(target_os = "wasi")] -#[inline] -pub(crate) fn current_cycle() -> u64 { - use wasi::wasi_unstable::{clock_time_get, CLOCK_MONOTONIC}; - clock_time_get(CLOCK_MONOTONIC, 1_000_000).unwrap_or(0) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_now() { - let mut prev = current_cycle(); - for _ in 0..100 { - let n = current_cycle(); - assert!(n >= prev); - prev = n; - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 174c180..d3151a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,6 @@ #![cfg_attr(docsrs, feature(doc_cfg))] -mod coarse_now; mod instant; #[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))] mod tsc_now; @@ -61,15 +60,22 @@ pub fn is_tsc_available() -> bool { #[inline] pub(crate) fn current_cycle() -> u64 { + let coarse_cycle = || { + let coarse = coarsetime::Instant::now_without_cache_update(); + coarsetime::Duration::from_ticks(coarse.as_ticks()).as_nanos() + }; + #[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))] - if is_tsc_available() { - tsc_now::current_cycle() - } else { - coarse_now::current_cycle() + { + if tsc_now::is_tsc_available() { + tsc_now::current_cycle() + } else { + coarse_cycle() + } } #[cfg(not(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64"))))] { - coarse_now::current_cycle() + coarse_cycle() } } @@ -123,7 +129,7 @@ mod tests { let duration_ns_std = std_instant.elapsed(); #[cfg(target_os = "windows")] - let expect_max_delta_ns = 20_000_000; + let expect_max_delta_ns = 40_000_000; #[cfg(not(target_os = "windows"))] let expect_max_delta_ns = 5_000_000;