quanta

Struct Upkeep

source
pub struct Upkeep { /* private fields */ }
Expand description

Ultra-low-overhead access to slightly-delayed time.

In some applications, there can be a need to check the current time very often, so much so that the overhead of checking the time can begin to eat up measurable overhead. For some of these cases, the time may need to be accessed often but does not necessarily need to be incredibly accurate: one millisecond granularity could be entirely acceptable.

For these cases, we provide a slightly-delayed version of the time to callers via Clock::recent, which is updated by a background upkeep thread. That thread is configured and spanwed via Upkeep.

Upkeep can construct a new clock (or be passed an existing clock to use), and given an update interval, and it will faithfully attempt to update the global recent time on the specified interval. There is a trade-off to be struck in terms of how often the time is updated versus the required accuracy. Checking the time and updating the global reference is itself not zero-cost, and so care must be taken to analyze the number of readers in order to ensure that, given a particular update interval, the upkeep thread is saving more CPU time than would be spent otherwise by directly querying the current time.

The recent time is read and written atomically. It is global to an application, so if another codepath creates the upkeep thread, the interval chosen by that instantiation will be the one that all callers of Clock::recent end up using.

Multiple upkeep threads cannot exist at the same time. A new upkeep thread can be started if the old one is dropped and returns.

In terms of performance, reading the recent time can be up to two to three times as fast as reading the current time in the optimized case of using the Time Stamp Counter source. In practice, while a caller might expect to take 12-14ns to read the TSC and scale it to reference time, the recent time can be read in 4-5ns, with no reference scale conversion required.

Implementations§

source§

impl Upkeep

source

pub fn new(interval: Duration) -> Upkeep

Creates a new Upkeep.

This creates a new internal clock for acquiring the current time. If you have an existing Clock that is already calibrated, it is slightly faster to clone it and construct the builder with new_with_clock to avoid recalibrating.

source

pub fn new_with_clock(interval: Duration, clock: Clock) -> Upkeep

Creates a new Upkeep with the specified Clock instance.

source

pub fn start(self) -> Result<Handle, Error>

Start the upkeep thread, periodically updating the global coarse time.

Handle represents a drop guard for the upkeep thread if it is successfully spawned. Dropping the handle will also instruct the upkeep thread to stop and exist, so the handle must be held while the upkeep thread should continue to run.

§Errors

If either an existing upkeep thread is running, or there was an issue when attempting to spawn the upkeep thread, an error variant will be returned describing the error.

Trait Implementations§

source§

impl Debug for Upkeep

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Upkeep

§

impl RefUnwindSafe for Upkeep

§

impl Send for Upkeep

§

impl Sync for Upkeep

§

impl Unpin for Upkeep

§

impl UnwindSafe for Upkeep

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.