-
-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Increase the accuracy of time measurements by replacing
most uses of `quanta::Instant` with `std::time::Instant`
- Loading branch information
1 parent
cdfad26
commit e681c1f
Showing
20 changed files
with
548 additions
and
673 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,10 @@ | ||
use std::time::Duration; | ||
|
||
#[cfg_attr(feature = "quanta", path = "time/clock_quanta.rs")] | ||
#[cfg_attr(not(feature = "quanta"), path = "time/clock_compat.rs")] | ||
pub(crate) mod clock; | ||
mod atomic_time; | ||
mod clock; | ||
mod instant; | ||
|
||
pub(crate) use atomic_time::AtomicInstant; | ||
pub(crate) use clock::Clock; | ||
pub(crate) use instant::Instant; | ||
|
||
#[cfg(test)] | ||
pub(crate) use clock::Mock; | ||
|
||
/// a wrapper type over Instant to force checked additions and prevent | ||
/// unintentional overflow. The type preserve the Copy semantics for the wrapped | ||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] | ||
pub(crate) struct Instant(clock::Instant); | ||
|
||
pub(crate) trait CheckedTimeOps { | ||
fn checked_add(&self, duration: Duration) -> Option<Self> | ||
where | ||
Self: Sized; | ||
|
||
fn checked_duration_since(&self, earlier: Self) -> Option<Duration> | ||
where | ||
Self: Sized; | ||
} | ||
|
||
impl Instant { | ||
pub(crate) fn new(instant: clock::Instant) -> Instant { | ||
Instant(instant) | ||
} | ||
|
||
pub(crate) fn now() -> Instant { | ||
Instant(clock::Instant::now()) | ||
} | ||
|
||
#[cfg(feature = "quanta")] | ||
pub(crate) fn inner_clock(self) -> clock::Instant { | ||
self.0 | ||
} | ||
} | ||
|
||
impl CheckedTimeOps for Instant { | ||
fn checked_add(&self, duration: Duration) -> Option<Instant> { | ||
self.0.checked_add(duration).map(Instant) | ||
} | ||
|
||
fn checked_duration_since(&self, earlier: Self) -> Option<Duration> | ||
where | ||
Self: Sized, | ||
{ | ||
self.0.checked_duration_since(earlier.0) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use crate::common::time::Instant; | ||
|
||
use portable_atomic::AtomicU64; | ||
use std::sync::atomic::Ordering; | ||
|
||
/// `AtomicInstant` is a wrapper around `AtomicU64` that provides thread-safe access | ||
/// to an `Instant`. | ||
/// | ||
/// `u64::MAX` is used to represent an unset `Instant`. | ||
#[derive(Debug)] | ||
pub(crate) struct AtomicInstant { | ||
instant: AtomicU64, | ||
} | ||
|
||
impl Default for AtomicInstant { | ||
/// Creates a new `AtomicInstant` with an unset `Instant`. | ||
fn default() -> Self { | ||
Self { | ||
instant: AtomicU64::new(u64::MAX), | ||
} | ||
} | ||
} | ||
|
||
impl AtomicInstant { | ||
/// Creates a new `AtomicInstant` with the given `Instant`. | ||
pub(crate) fn new(instant: Instant) -> Self { | ||
// Ensure the `Instant` is not `u64::MAX`, which means unset. | ||
debug_assert!(instant.as_nanos() != u64::MAX); | ||
|
||
Self { | ||
instant: AtomicU64::new(instant.as_nanos()), | ||
} | ||
} | ||
|
||
/// Clears the `Instant`. | ||
pub(crate) fn clear(&self) { | ||
self.instant.store(u64::MAX, Ordering::Release); | ||
} | ||
|
||
/// Returns `true` if the `Instant` is set. | ||
pub(crate) fn is_set(&self) -> bool { | ||
self.instant.load(Ordering::Acquire) != u64::MAX | ||
} | ||
|
||
/// Returns the `Instant` if it is set, otherwise `None`. | ||
pub(crate) fn instant(&self) -> Option<Instant> { | ||
let ts = self.instant.load(Ordering::Acquire); | ||
if ts == u64::MAX { | ||
None | ||
} else { | ||
Some(Instant::from_nanos(ts)) | ||
} | ||
} | ||
|
||
/// Sets the `Instant`. | ||
pub(crate) fn set_instant(&self, instant: Instant) { | ||
// Ensure the `Instant` is not `u64::MAX`, which means unset. | ||
debug_assert!(instant.as_nanos() != u64::MAX); | ||
|
||
self.instant.store(instant.as_nanos(), Ordering::Release); | ||
} | ||
} |
Oops, something went wrong.