Skip to main content

HandshakeHeader

Struct HandshakeHeader 

Source
pub struct HandshakeHeader {
    pub generation: AtomicU32,
    pub strategy_tag: AtomicU32,
    pub in_flight: [AtomicU64; 2],
    /* private fields */
}
Expand description

Layout invariant: 64-byte aligned, 128 bytes total (two cache lines).

Line 0 is read-mostly (generation + strategy tag). Line 1 is write-hot (in-flight counters for the two live generations).

Fields§

§generation: AtomicU32

Current generation. Op entry captures this; migration bumps it.

§strategy_tag: AtomicU32

PIC strategy tag. Hot-path branch target. One byte semantically; stored as u32 for atomic alignment.

§in_flight: [AtomicU64; 2]

In-flight op counts, one slot per generation parity. Indexed by generation & 1. Op entry increments; exit decrements.

Implementations§

Source§

impl HandshakeHeader

Source

pub const fn new() -> Self

Source

pub fn enter_op(&self) -> u32

Enter an op. Returns the captured generation, which the caller must pass to Self::exit_op to release the in-flight slot.

Uses the standard RCU/epoch double-check pattern: load the generation, increment the matching in_flight slot, re-load the generation; retry if the generation changed between loads. This closes the race where a migration completes (bump + drain + free) after the first load but before the increment, which would otherwise leave the reader holding an in_flight slot on a freed generation.

Adds ~1 cycle (a second Acquire load) on the common no-migration path. The Acquire on the in-flight fetch_add also enables the pair state.store(Release) + fence(SeqCst) + in_flight.load(Acquire) for primitives that need to skip wakeups when no waiters exist.

Source

pub fn in_flight_count(&self, generation: u32) -> u64

Read the in-flight count for a given generation.

Used by primitive coordinators to decide whether to skip wakeup after a state transition. For the safe skip-wakeup pattern, pair this with a SeqCst fence after the state store and use Acquire ordering on this load.

Source

pub fn exit_op(&self, captured_gen: u32)

Source

pub fn tag(&self) -> u32

Read the current strategy tag without entering an op.

Source

pub fn bump_generation(&self) -> u32

Bump generation only. Used for data-layout migration without changing the strategy tag.

Returns the old generation so the caller can drain its in-flight slot.

Source

pub fn set_tag(&self, new_tag: u32)

Set the strategy tag in place. PIC-only update; does NOT bump generation. Use when the strategy change does not require any data-layout migration (e.g., switching wait strategy in a once-shot primitive).

Source

pub fn migrate(&self, new_tag: u32) -> u32

Bump generation and atomically swap the strategy tag.

After this returns, new ops will read the new tag; in-flight ops on the old generation continue to completion. Returns the old generation so the caller can wait on its in-flight counter.

Source

pub fn drain(&self, generation: u32)

Wait until the given generation has zero in-flight ops.

Spins. Caller is the migration coordinator and migration is rare, so spinning is acceptable here.

Trait Implementations§

Source§

impl Default for HandshakeHeader

Source§

fn default() -> Self

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

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.