adaptive_barrier

Struct Barrier

Source
pub struct Barrier(/* private fields */);
Expand description

A Barrier to synchronize multiple threads.

Multiple threads can meet on a single barrier to synchronize a “meeting point” in a computation (eg. when they need to pass results to others), much like the Barrier from the standard library.

Unlike that, the expected number of threads waiting for the barrier is not preset in the new call, but autodetected and adapted to at runtime.

The way this is done is by cloning the original Barrier ‒ for a group to continue after wait, a wait needs to be called on each clone. This allows to add or remove (even implicitly by panicking) the clones as needed.

§Examples


let barrier = Barrier::new(PanicMode::Poison);
let mut threads = Vec::new();
for _ in 0..4 {
    // Each thread gets its own clone of the barrier. They are tied together, not independent.
    let mut barrier = barrier.clone();
    let thread = thread::spawn(move || {
        // Wait to start everything at the same time
        barrier.wait();

        // ... Do some work that needs to start synchronously ...
        // Now, if this part panics, it will *not* deadlock, it'll unlock the others just fine
        // and propagate the panic (see the parameter to new(..)

        // Wait for all threads to finish
        if barrier.wait().is_leader() {
            // Pick one thread to consolidate the results here

            // Note that as we don't call wait any more, if we panic here, it'll not get
            // propagated through the barrier any more.
        }
    });
    threads.push(thread);
}

// Watch out for the last instance here in the main/controlling thread. You can either call
// wait on it too, or make sure it is dropped. If you don't, others will keep waiting for it.
drop(barrier);

for thread in threads {
    thread.join().expect("Propagating thread panic");
}

Implementations§

Source§

impl Barrier

Source

pub fn new(panic_mode: PanicMode) -> Self

Creates a new (independent) barrier.

To create more handles to the same barrier, clone it.

The panic mode specifies what to do if a barrier observes a panic (is dropped while panicking).

Source

pub fn wait(&mut self) -> WaitResult

Wait for all the other threads to wait too.

This’ll block until all threads holding clones of the same barrier call wait.

§Panics

If the barrier was created with PanicMode::Poison and some other clone of the barrier observed a panic, this’ll also panic (even if it was already parked inside).

Trait Implementations§

Source§

impl Clone for Barrier

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Barrier

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for Barrier

Source§

fn default() -> Self

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

impl Drop for Barrier

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl UnwindSafe for Barrier

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.