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: AtomicU32Current generation. Op entry captures this; migration bumps it.
strategy_tag: AtomicU32PIC 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
impl HandshakeHeader
pub const fn new() -> Self
Sourcepub fn enter_op(&self) -> u32
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.
Sourcepub fn in_flight_count(&self, generation: u32) -> u64
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.
pub fn exit_op(&self, captured_gen: u32)
Sourcepub fn bump_generation(&self) -> u32
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.
Sourcepub fn set_tag(&self, new_tag: u32)
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).