synchronoise::phaser

Struct WriterReaderPhaser

Source
pub struct WriterReaderPhaser { /* private fields */ }
Expand description

A synchronization primitive that allows for multiple concurrent wait-free “writer critical sections” and a “reader phase flip” that can wait for all currently-active writers to finish.

The basic interaction setup for a WriterReaderPhaser is as follows:

  • Any number of writers can open and close a “writer critical section” with no waiting.
  • Zero or one readers can be active at one time, by holding a “read lock”. Any reader who wishes to open a “read lock” while another one is active is blocked until the previous one finishes.
  • The holder of a read lock may request a “phase flip”, which causes the reader to wait until all current writer critical sections are finished before continuing.

WriterReaderPhaser is a port of the primitive of the same name from HdrHistogram. For a summary of the rationale behind its design, see this post by its author. Part of its assumptions is that this primitive is synchronizing access to a double-buffered set of counters, and the readers are expected to swap the buffers while holding a read lock but before flipping the phase. This allows them to access a stable sample to read and perform calculations from, while writers still have wait-free synchronization.

“Writer critical sections” and “read locks” are represented by guard structs that allow scope-based resource management of the counters and locks.

  • The PhaserCriticalSection atomically increments and decrements the phase counters upon creation and drop. These operations use std::sync::atomic::AtomicIsize from the standard library, and provide no-wait handling for platforms with atomic addition instructions.
  • The PhaserReadLock is kept in the WriterReaderPhaser as a Mutex, enforcing the mutual exclusion of the read lock. The “phase flip” operation is defined on the read lock guard itself, enforcing that only the holder of a read lock can execute one.

Implementations§

Source§

impl WriterReaderPhaser

Source

pub fn new() -> WriterReaderPhaser

Creates a new WriterReaderPhaser.

Source

pub fn writer_critical_section(&self) -> PhaserCriticalSection

Enters a writer critical section, returning a guard object that signals the end of the critical section upon drop.

Source

pub fn read_lock(&self) -> LockResult<MutexGuard<'_, PhaserReadLock>>

Enter a reader criticial section, potentially blocking until a currently active read section finishes. Returns a guard object that allows the user to flip the phase of the WriterReaderPhaser, and unlocks the read lock upon drop.

§Errors

If another reader critical section panicked while holding the read lock, this call will return an error once the lock is acquired. See the documentation for std::sync::Mutex::lock for details.

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

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 56 bytes