Struct heron::rapier_plugin::rapier2d::crossbeam::utils::Backoff[]

pub struct Backoff { /* fields omitted */ }
Expand description

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 crossbeam_utils::Backoff;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;

fn fetch_mul(a: &AtomicUsize, b: usize) -> usize {
    let backoff = Backoff::new();
    loop {
        let val = a.load(SeqCst);
        if a.compare_exchange(val, val.wrapping_mul(b), SeqCst, SeqCst).is_ok() {
            return val;
        }
        backoff.spin();
    }
}

Waiting for an AtomicBool to become true:

use crossbeam_utils::Backoff;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;

fn spin_wait(ready: &AtomicBool) {
    let backoff = Backoff::new();
    while !ready.load(SeqCst) {
        backoff.snooze();
    }
}

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 crossbeam_utils::Backoff;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::thread;

fn blocking_wait(ready: &AtomicBool) {
    let backoff = Backoff::new();
    while !ready.load(SeqCst) {
        if backoff.is_completed() {
            thread::park();
        } else {
            backoff.snooze();
        }
    }
}

Implementations

Creates a new Backoff.

Examples
use crossbeam_utils::Backoff;

let backoff = Backoff::new();

Resets the Backoff.

Examples
use crossbeam_utils::Backoff;

let backoff = Backoff::new();
backoff.reset();

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 crossbeam_utils::Backoff;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;

fn fetch_mul(a: &AtomicUsize, b: usize) -> usize {
    let backoff = Backoff::new();
    loop {
        let val = a.load(SeqCst);
        if a.compare_exchange(val, val.wrapping_mul(b), SeqCst, SeqCst).is_ok() {
            return val;
        }
        backoff.spin();
    }
}

let a = AtomicUsize::new(7);
assert_eq!(fetch_mul(&a, 8), 7);
assert_eq!(a.load(SeqCst), 56);

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 to spin.

If possible, use is_completed to check when it is advised to stop using backoff and block the current thread using a different synchronization mechanism instead.

Examples

Waiting for an AtomicBool to become true:

use crossbeam_utils::Backoff;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::thread;
use std::time::Duration;

fn spin_wait(ready: &AtomicBool) {
    let backoff = Backoff::new();
    while !ready.load(SeqCst) {
        backoff.snooze();
    }
}

let ready = Arc::new(AtomicBool::new(false));
let ready2 = ready.clone();

thread::spawn(move || {
    thread::sleep(Duration::from_millis(100));
    ready2.store(true, SeqCst);
});

assert_eq!(ready.load(SeqCst), false);
spin_wait(&ready);
assert_eq!(ready.load(SeqCst), true);

Returns true if exponential backoff has completed and blocking the thread is advised.

Examples

Waiting for an AtomicBool to become true and parking the thread after a long wait:

use crossbeam_utils::Backoff;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::thread;
use std::time::Duration;

fn blocking_wait(ready: &AtomicBool) {
    let backoff = Backoff::new();
    while !ready.load(SeqCst) {
        if backoff.is_completed() {
            thread::park();
        } else {
            backoff.snooze();
        }
    }
}

let ready = Arc::new(AtomicBool::new(false));
let ready2 = ready.clone();
let waiter = thread::current();

thread::spawn(move || {
    thread::sleep(Duration::from_millis(100));
    ready2.store(true, SeqCst);
    waiter.unpark();
});

assert_eq!(ready.load(SeqCst), false);
blocking_wait(&ready);
assert_eq!(ready.load(SeqCst), true);

Trait Implementations

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait. Read more

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait. Read more

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s. Read more

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s. Read more

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait. Read more

Performs the conversion.

Creates Self using data from the given [World]

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Performs the conversion.

The alignment of pointer.

The type for initializers.

Initializes a with the given initializer. Read more

Dereferences the given pointer. Read more

Mutably dereferences the given pointer. Read more

Drops the object pointed to by the given pointer. Read more

Should always be Self

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more

Checks if self is actually part of its subset T (and can be converted to it).

Use with care! Same as self.to_subset but without any property checks. Always succeeds.

The inclusion map: converts self to the equivalent element of its superset.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more