Struct Backoff
struct Backoff { ... }
Performs exponential backoff in spin loops.
Backing off in spin loops reduces contention and improves overall performance.
This primitive can execute YIELD and PAUSE instructions, yield the current thread to the OS scheduler, and tell when is a good time to block the thread using a different synchronization mechanism. Each step of the back off procedure takes roughly twice as long as the previous step.
Examples
Backing off in a lock-free loop:
use Backoff;
use AtomicUsize;
use SeqCst;
Waiting for an AtomicBool to become true:
use Backoff;
use AtomicBool;
use SeqCst;
Waiting for an AtomicBool to become true and parking the thread after a long wait.
Note that whoever sets the atomic variable to true must notify the parked thread by calling
unpark():
use Backoff;
use AtomicBool;
use SeqCst;
use thread;
Implementations
impl Backoff
fn new() -> SelfCreates a new
Backoff.Examples
use Backoff; let backoff = new;fn reset(self: &Self)Resets the
Backoff.Examples
use Backoff; let backoff = new; backoff.reset;fn spin(self: &Self)Backs off in a lock-free loop.
This method should be used when we need to retry an operation because another thread made progress.
The processor may yield using the YIELD or PAUSE instruction.
Examples
Backing off in a lock-free loop:
use Backoff; use AtomicUsize; use SeqCst; let a = new; assert_eq!; assert_eq!;fn snooze(self: &Self)Backs off in a blocking loop.
This method should be used when we need to wait for another thread to make progress.
The processor may yield using the YIELD or PAUSE instruction and the current thread may yield by giving up a timeslice to the OS scheduler.
In
#[no_std]environments, this method is equivalent tospin.If possible, use
is_completedto check when it is advised to stop using backoff and block the current thread using a different synchronization mechanism instead.Examples
Waiting for an
AtomicBoolto becometrue:use Backoff; use Arc; use AtomicBool; use SeqCst; use thread; use Duration; let ready = new; let ready2 = ready.clone; spawn; assert_eq!; spin_wait; assert_eq!; # sleep; // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371fn is_completed(self: &Self) -> boolReturns
trueif exponential backoff has completed and blocking the thread is advised.Examples
Waiting for an
AtomicBoolto becometrueand parking the thread after a long wait:use Backoff; use Arc; use AtomicBool; use SeqCst; use thread; use Duration; let ready = new; let ready2 = ready.clone; let waiter = current; spawn; assert_eq!; blocking_wait; assert_eq!; # sleep; // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
impl Debug for Backoff
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl Default for Backoff
fn default() -> Backoff
impl Freeze for Backoff
impl RefUnwindSafe for Backoff
impl Send for Backoff
impl Sync for Backoff
impl Unpin for Backoff
impl UnwindSafe for Backoff
impl<T> Any for Backoff
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Backoff
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Backoff
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> From for Backoff
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for Backoff
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Backoff
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Backoff
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>