pub struct AtomicInstant(/* private fields */);std only.Expand description
Atomic version of Instant.
Values are encoded relative to a process-local baseline pairing
std::time::SystemTime::now() with std::time::Instant::now() (see
crate::utils::encode_instant_to_duration and
crate::utils::decode_instant_from_duration). Within the same process,
values in the platform’s representable Instant range round-trip exactly.
Encodings are not portable across processes or restarts: there they only
approximate wall-clock time and must not be used as persistent deadlines.
System clock adjustments can affect that cross-process interpretation, while
behavior across system sleep follows the platform’s Instant semantics.
With the serde feature, this type retains its Duration proxy wire
format. For persistent wall-clock values, use crate::AtomicSystemTime.
Implementations§
Source§impl AtomicInstant
impl AtomicInstant
Sourcepub fn now() -> Self
pub fn now() -> Self
Returns the instant corresponding to “now”.
§Examples
use atomic_time::AtomicInstant;
let now = AtomicInstant::now();Sourcepub fn swap(&self, instant: Instant, order: Ordering) -> Instant
pub fn swap(&self, instant: Instant, order: Ordering) -> Instant
Stores a value into the atomic instant, returning the previous value.
Sourcepub fn compare_exchange(
&self,
current: Instant,
new: Instant,
success: Ordering,
failure: Ordering,
) -> Result<Instant, Instant>
pub fn compare_exchange( &self, current: Instant, new: Instant, success: Ordering, failure: Ordering, ) -> Result<Instant, Instant>
Stores a value into the atomic instant if the current value is the same as the current
value.
Sourcepub fn compare_exchange_weak(
&self,
current: Instant,
new: Instant,
success: Ordering,
failure: Ordering,
) -> Result<Instant, Instant>
pub fn compare_exchange_weak( &self, current: Instant, new: Instant, success: Ordering, failure: Ordering, ) -> Result<Instant, Instant>
Stores a value into the atomic instant if the current value is the same as the current
value.
Sourcepub fn try_update<F>(
&self,
set_order: Ordering,
fetch_order: Ordering,
f: F,
) -> Result<Instant, Instant>
pub fn try_update<F>( &self, set_order: Ordering, fetch_order: Ordering, f: F, ) -> Result<Instant, Instant>
Fetches the value and applies a function that can choose whether to store a new value.
Returns Ok(previous_value) when f returns Some(_), and
Err(previous_value) when it returns None. The closure can run more
than once when another thread changes the value concurrently, but it is
applied only once to the value that is stored.
set_order describes the ordering of the successful update and
fetch_order describes failed compare-and-exchange loads. They have the
same requirements as the success and failure orderings of
compare_exchange.
§Examples
use atomic_time::AtomicInstant;
use std::{sync::atomic::Ordering, time::{Duration, Instant}};
let start = Instant::now();
let x = AtomicInstant::new(start);
assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(start));
assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |old| Some(old + Duration::from_secs(1))), Ok(start));Sourcepub fn fetch_update<F>(
&self,
set_order: Ordering,
fetch_order: Ordering,
f: F,
) -> Result<Instant, Instant>
pub fn fetch_update<F>( &self, set_order: Ordering, fetch_order: Ordering, f: F, ) -> Result<Instant, Instant>
Fetches the value, and applies a function to it that returns an optional
new value. Returns a Result of Ok(previous_value) if the function returned Some(_), else
Err(previous_value).
Note: This may call the function multiple times if the value has been changed from other threads in
the meantime, as long as the function returns Some(_), but the function will have been applied
only once to the stored value.
fetch_update takes two Ordering arguments to describe the memory ordering of this operation.
The first describes the required ordering for when the operation finally succeeds while the second
describes the required ordering for loads. These correspond to the success and failure orderings of
compare_exchange respectively.
Using Acquire as success ordering makes the store part
of this operation Relaxed, and using Release makes the final successful load
Relaxed. The (failed) load ordering can only be SeqCst, Acquire or Relaxed
and must be equivalent to or weaker than the success ordering.
§Examples
use atomic_time::AtomicInstant;
use std::{time::{Duration, Instant}, sync::atomic::Ordering};
let now = Instant::now();
let x = AtomicInstant::new(now);
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(now));
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + Duration::from_secs(1))), Ok(now));
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + Duration::from_secs(1))), Ok(now + Duration::from_secs(1)));
assert_eq!(x.load(Ordering::SeqCst), now + Duration::from_secs(2));Sourcepub fn update<F>(
&self,
set_order: Ordering,
fetch_order: Ordering,
f: F,
) -> Instant
pub fn update<F>( &self, set_order: Ordering, fetch_order: Ordering, f: F, ) -> Instant
Fetches the value, applies a function to produce a new value, stores it, and returns the previous value.
The closure can run more than once when another thread changes the value
concurrently, but it is applied only once to the value that is stored.
set_order and fetch_order have the same requirements as the success
and failure orderings of compare_exchange.
§Examples
use atomic_time::AtomicInstant;
use std::{sync::atomic::Ordering, time::{Duration, Instant}};
let start = Instant::now();
let x = AtomicInstant::new(start);
assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |old| old + Duration::from_secs(1)), start);
assert_eq!(x.load(Ordering::SeqCst), start + Duration::from_secs(1));Sourcepub fn fetch_min(&self, val: Instant, order: Ordering) -> Instant
pub fn fetch_min(&self, val: Instant, order: Ordering) -> Instant
Atomically stores the smaller of the current value and val, returning
the previous value.
The ordering compares values encoded with this process’s baseline. It is
meaningful only for Instant values using the same process-local
baseline; it does not assign ordering semantics across processes or
process restarts. order describes the memory ordering of the
read-modify-write operation. Using Acquire makes
its store part relaxed, and using Release makes its
load part relaxed.
§Examples
use atomic_time::AtomicInstant;
use std::{sync::atomic::Ordering, time::{Duration, Instant}};
let middle = Instant::now();
let low = middle - Duration::from_secs(1);
let high = middle + Duration::from_secs(1);
let x = AtomicInstant::new(middle);
assert_eq!(x.fetch_min(high, Ordering::SeqCst), middle);
assert_eq!(x.fetch_min(low, Ordering::SeqCst), middle);
assert_eq!(x.load(Ordering::SeqCst), low);Sourcepub fn fetch_max(&self, val: Instant, order: Ordering) -> Instant
pub fn fetch_max(&self, val: Instant, order: Ordering) -> Instant
Atomically stores the larger of the current value and val, returning
the previous value.
The ordering compares values encoded with this process’s baseline. It is
meaningful only for Instant values using the same process-local
baseline; it does not assign ordering semantics across processes or
process restarts. order describes the memory ordering of the
read-modify-write operation. Using Acquire makes
its store part relaxed, and using Release makes its
load part relaxed.
§Examples
use atomic_time::AtomicInstant;
use std::{sync::atomic::Ordering, time::{Duration, Instant}};
let middle = Instant::now();
let low = middle - Duration::from_secs(1);
let high = middle + Duration::from_secs(1);
let x = AtomicInstant::new(middle);
assert_eq!(x.fetch_max(low, Ordering::SeqCst), middle);
assert_eq!(x.fetch_max(high, Ordering::SeqCst), middle);
assert_eq!(x.load(Ordering::SeqCst), high);Sourcepub fn is_lock_free() -> bool
pub fn is_lock_free() -> bool
Returns true if operations on values of this type are lock-free.
If the compiler or the platform doesn’t support the necessary
atomic instructions, global locks for every potentially
concurrent atomic operation will be used.
§Examples
use atomic_time::AtomicInstant;
let is_lock_free = AtomicInstant::is_lock_free();Sourcepub const fn is_always_lock_free() -> bool
pub const fn is_always_lock_free() -> bool
Returns whether operations on values of this type are always lock-free.
A false result does not preclude lock-free operations selected through
runtime CPU feature detection; use is_lock_free
to query the current target at runtime.
§Examples
use atomic_time::AtomicInstant;
const ALWAYS_LOCK_FREE: bool = AtomicInstant::is_always_lock_free();
let _ = ALWAYS_LOCK_FREE;Sourcepub fn into_inner(self) -> Instant
pub fn into_inner(self) -> Instant
Consumes the atomic and returns the contained value.
This is safe because passing self by value guarantees that no other threads are
concurrently accessing the atomic data.
Trait Implementations§
Source§impl Debug for AtomicInstant
impl Debug for AtomicInstant
Source§impl<'de> Deserialize<'de> for AtomicInstant
Available on crate feature serde only.
impl<'de> Deserialize<'de> for AtomicInstant
serde only.