diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14cd99e..b3c8dd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ jobs: strategy: matrix: os: [macos-latest, ubuntu-latest, windows-latest] + features: ["atomic", "atomic,fallback-coarse"] rust: [stable] env: RUST_BACKTRACE: 1 @@ -29,13 +30,13 @@ jobs: - name: Check format run: cargo fmt --all -- --check - name: Build - run: cargo build --workspace --all-targets --all-features + run: cargo build --workspace --all-targets --features ${{ matrix.features }} - name: Clippy - run: cargo clippy --workspace --all-targets --all-features -- -D warnings + run: cargo clippy --workspace --all-targets --features ${{ matrix.features }} -- -D warnings - name: Run tests - run: cargo test --workspace --all-targets --all-features -- --nocapture + run: cargo test --workspace --all-targets --features ${{ matrix.features }} -- --nocapture - name: Run benches - run: cargo bench --workspace --all-targets --all-features + run: cargo bench --workspace --all-targets --features ${{ matrix.features }} build-wasm: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 8c223fb..15f900e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minstant" -version = "0.1.6" +version = "0.1.7" authors = ["The TiKV Authors"] edition = "2021" license = "MIT" @@ -16,11 +16,12 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] ctor = "0.1.20" -coarsetime = "0.1" +coarsetime = { version = "0.1", optional = true } web-time = "1.0" [features] atomic = [] +fallback-coarse = ["coarsetime"] [dev-dependencies] criterion = "0.3" diff --git a/README.md b/README.md index e9f3749..c98d5f5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,14 @@ This library is used by a high performance tracing library [`minitrace-rust`](ht ## Platform Support -Currently, only the Linux on `x86` or `x86_64` is backed by [TSC](https://en.wikipedia.org/wiki/Time_Stamp_Counter). On other platforms, `minstant` falls back to coarse time. If TSC is unstable, it will also fall back to coarse time. +Currently, only the Linux on `x86` or `x86_64` is backed by [TSC](https://en.wikipedia.org/wiki/Time_Stamp_Counter). On other platforms, `minstant` falls back to `std::time`. If TSC is unstable, it will also fall back to `std::time`. + +If speed is privileged over accuracy when fallback occurs, you can use `fallback-corase` feature to use corase time: + +```toml +[dependencies] +minstant = { version = "0.1", features = ["fallback-coarse"] } +``` ## Benchmark diff --git a/src/instant.rs b/src/instant.rs index dd54e0e..03e3099 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -14,6 +14,9 @@ use web_time::{SystemTime, UNIX_EPOCH}; pub struct Instant(u64); impl Instant { + /// A default `Instant` that can be seen as a fixed but random moment. + pub const ZERO: Instant = Instant(0); + #[inline] /// Returns an instant corresponding to "now". /// diff --git a/src/lib.rs b/src/lib.rs index 77b8247..f34d8ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,25 +60,34 @@ 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 tsc_now::is_tsc_available() { tsc_now::current_cycle() } else { - coarse_cycle() + current_cycle_fallback() } } #[cfg(not(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64"))))] { - coarse_cycle() + current_cycle_fallback() } } +#[cfg(not(feature = "fallback-coarse"))] +pub(crate) fn current_cycle_fallback() -> u64 { + web_time::SystemTime::now() + .duration_since(web_time::UNIX_EPOCH) + .map(|d| d.as_nanos() as u64) + .unwrap_or(0) +} + +#[cfg(feature = "fallback-coarse")] +pub(crate) fn current_cycle_fallback() -> u64 { + let coarse = coarsetime::Instant::now_without_cache_update(); + coarsetime::Duration::from_ticks(coarse.as_ticks()).as_nanos() +} + #[inline] pub(crate) fn nanos_per_cycle() -> f64 { #[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]