Skip to main content

chronon::sender::IArbitratablePort

More...

#include <Port.hpp>

Inherited by chronon::sender::InPort< T >

Public Functions

Name
virtual~IArbitratablePort() =default
virtual uint64_tstagingOverflowEvents() const
virtual voidsetArbitrationProgressPointers(std::vector< const std::atomic< uint64_t > * > ptrs) =0
virtual voidsetArbitrationConnProgress(const std::unordered_map< Unit *, const std::atomic< uint64_t > * > & )
virtual boolmpscConnProgressFullyResolved() const
virtual voidarbitrateMPSCConsumerDriven()
virtual voidarbitrateMPSC() =0
virtual void *arbitratablePortKey() =0

Detailed Description

class chronon::sender::IArbitratablePort;

IArbitratablePort - Type-erased interface exposing the per-cycle MPSC arbitration hook to the TickSimulation scheduler.

Only InPorts that have at least one MPSC connection registered implement meaningful behavior; other ports can ignore. TickSimulation keeps a flat list of ports that declared MPSC interest during initialize() and calls arbitrateMPSC() on each at every cycle boundary (sequential tick loop, executeEpochBarrier sync_wait, or the progress-based lookahead scheduler's epoch-end flush).

Public Functions Documentation

function ~IArbitratablePort

virtual ~IArbitratablePort() =default

function stagingOverflowEvents

inline virtual uint64_t stagingOverflowEvents() const

Reimplemented by: chronon::InPort::stagingOverflowEvents, chronon::sender::InPort::stagingOverflowEvents

Number of staged pushes dropped because the physical MPSC ring was full. Nonzero indicates the lookahead window outran the ring capacity — a correctness failure. Surfaced for the epoch-free A/B watchdog. Default 0 for ports with no multi-producer staging.

function setArbitrationProgressPointers

virtual void setArbitrationProgressPointers(
std::vector< const std::atomic< uint64_t > * > ptrs
) =0

Reimplemented by: chronon::InPort::setArbitrationProgressPointers, chronon::sender::InPort::setArbitrationProgressPointers

Install the predecessor-thread completed_cycle atomics for consumer-tick-driven arbitration. Called once during TickSimulation::initialize() for the lookahead scheduler. Ignored if empty or if the port has no MPSC connections.

function setArbitrationConnProgress

inline virtual void setArbitrationConnProgress(
const std::unordered_map< Unit *, const std::atomic< uint64_t > * > &
)

Reimplemented by: chronon::InPort::setArbitrationConnProgress, chronon::sender::InPort::setArbitrationConnProgress

Install PER-CONNECTION producer completed_cycle atomics for consumer-tick-driven arbitration. src_progress maps each producer Unit* to its cluster's completed_cycle atomic. The InPort resolves one atomic per MPSC connection (by connection source), enabling each connection to be drained up to its OWN producer's progress rather than the min across producers — required for correctness under heterogeneous edge delays (a low-delay producer's message must not be held back by a lagging high-delay producer on the same InPort). Default: no-op.

function mpscConnProgressFullyResolved

inline virtual bool mpscConnProgressFullyResolved() const

Reimplemented by: chronon::InPort::mpscConnProgressFullyResolved, chronon::sender::InPort::mpscConnProgressFullyResolved

True iff every MPSC connection on this port has a resolved per-connection producer progress atomic, i.e. the heterogeneous-delay-correct consumer-driven drain in arbitrateMPSCConsumerDriven() fully covers this port. When false, at least one connection relies on the central per-epoch arbitrateMPSC() flush to deliver its tail (an unresolved producer is skipped by the consumer-driven path), so the epoch-free scheduler — which has no per-epoch flush — must NOT be used. Conservative default: false, so unknown port types veto epoch-free execution. InPort overrides.

function arbitrateMPSCConsumerDriven

inline virtual void arbitrateMPSCConsumerDriven()

Reimplemented by: chronon::InPort::arbitrateMPSCConsumerDriven, chronon::sender::InPort::arbitrateMPSCConsumerDriven

Cycle-bounded arbitration for consumer-tick-driven execution (see docs/mpsc-atomic-publish.md). The owning InPort computes S = min over producer clusters of completed_cycle.load(acquire) and drains only entries with enqueue_cycle <= S, in conn_id order. A no-op if the port has no MPSC connections or if S has not advanced since the last arbitration.

Default implementation calls arbitrateMPSC() — safe fallback for ports that don't need the bounded variant.

function arbitrateMPSC

virtual void arbitrateMPSC() =0

Reimplemented by: chronon::InPort::arbitrateMPSC, chronon::sender::InPort::arbitrateMPSC

Drain every staged entry whose epoch matches. Called at scheduler sync points (Sequential per-cycle, Barrier sync_wait, lookahead epoch-end flush) where every producer has finished its cycle.

function arbitratablePortKey

virtual void * arbitratablePortKey() =0

Reimplemented by: chronon::InPort::arbitratablePortKey, chronon::sender::InPort::arbitratablePortKey

Opaque identity for this arbitrable port. Returned by InPort as its this pointer (same value as destPortPtr() on connections). Used by TickSimulation to join MPSC InPorts against per-port producer- thread tables at init time.


Updated on 2026-07-06 at 09:03:33 +0000