Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
rte_election.h File Reference

N-way election primitive (ADR-039): generalizes rte_dual_negotiator's pairwise older-startup-timestamp-wins tie-break to RTE_REDUNDANCY_CONFIG_MAX_REPLICAS candidates, for the 2oo3/NMR topologies rte_dual_negotiator cannot express. More...

#include <stdbool.h>
#include <stdint.h>
#include "rte/redundancy/config/rte_redundancy_config.h"
#include "rte/redundancy/dual/rte_dual_types.h"
#include "rte/utils/status/rte_status.h"
Include dependency graph for rte_election.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rte_election_candidate_t
 One candidate's info for one rte_election_execute() call. The caller builds this array fresh each call from whatever transport it uses to learn about the other replicas - this module does not retain it between calls except via the state recomputed into rte_election_t itself. More...
struct  rte_election_t
 One rte_election_t instance's state. Caller-owned storage; every field is private - reach it only through the functions below. More...
struct  rte_election_config_t
 Configuration for rte_election_init(). More...

Functions

rte_status_t rte_election_init (rte_election_t *election, const rte_election_config_t *config)
 Initializes a rte_election_t. own_last_state starts at RTE_DUAL_STATE_IDLE (never yet evaluated).
rte_status_t rte_election_execute (rte_election_t *election, const rte_election_candidate_t *candidates, uint32_t candidate_count)
 Evaluates one round of election against the caller-supplied candidate snapshot (REQ-ELECTION-002 through -005). Empty snapshot (candidate_count == 0, or this instance's own_id not present in it) yields RTE_DUAL_STATE_UNKNOWN - no quorum to decide anything from, same "report, do not react" posture as rte_dual_negotiator_execute() on a lost peer.
rte_dual_state_t rte_election_get_own_state (const rte_election_t *election)
 Returns this instance's own current rte_dual_state_t, as of the last rte_election_execute() call.
rte_status_t rte_election_get_winner_id (const rte_election_t *election, uint32_t *out_id)
 Returns the last-elected winner's id.

Detailed Description

N-way election primitive (ADR-039): generalizes rte_dual_negotiator's pairwise older-startup-timestamp-wins tie-break to RTE_REDUNDANCY_CONFIG_MAX_REPLICAS candidates, for the 2oo3/NMR topologies rte_dual_negotiator cannot express.

Deliberately transport-agnostic, unlike rte_dual_negotiator (which owns an rte_dual_channel_t and drives its own beacon traffic): rte_dual_channel_t is inherently point-to-point (ADR-020 section 2), so there is no ready-made N-way beacon transport to build this on yet (ADR-039's own "shape TBD" note). Instead this module is a pure state-computation primitive - same posture as rte_voter_t, which already operates on caller-collected buffers rather than owning a channel of its own (ADR-025). The caller is responsible for gathering each cycle's candidate snapshot however its own topology's transport works (N pairwise rte_dual_channel_t instances, a broadcast link, etc. - out of this module's scope) and passing it to rte_election_execute() as a plain array.

Additive only: does not modify, replace, or get called by rte_dual_negotiator or rte_cross_comparator. The 2oo2 path (both of those, and everything built on them in RBC_GP today) is completely unaffected by this module's existence - it has no callers yet (ADR-039's own step 3, wiring GP's 2oo3/NMR path to this, is separate, not-yet-started scope).

REQ-ELECTION-001: no dynamic allocation; caller supplies storage and, each rte_election_execute() call, a caller-gathered candidate snapshot. REQ-ELECTION-002: the winner is the candidate with the OLDEST (smallest) startup_timestamp_ms among all candidates currently in contact (see REQ-ELECTION-004); on an exact timestamp tie, the smallest id wins - the same rule rte_dual_negotiator uses (REQ-DUAL-NEGOTIATOR-003), generalized from 2 to N candidates instead of special-cased for exactly 2. REQ-ELECTION-003: rte_election_execute() shall never call rte_safestate_enter() itself - same "no automatic safety reaction" posture as rte_dual_negotiator (REQ-DUAL-NEGOTIATOR-002): deciding what a sustained lack of quorum means for safety stays an application policy decision. REQ-ELECTION-004: a candidate not present in the snapshot passed to the current rte_election_execute() call (including this instance's own prior view of a candidate that has since dropped out) is treated as not currently in contact and cannot win that round - callers omit rather than mark timed-out candidates. REQ-ELECTION-005: every non-winning candidate that IS in contact is reported RTE_DUAL_STATE_HOTSTANDBY if the winner's own degraded flag is false, RTE_DUAL_STATE_COLDSTANDBY if true - the same "the ONLINE side's own degradation determines every STANDBY side's HOT/COLD label, never a STANDBY side's own self-report" rule rte_dual_negotiator uses (REQ-DUAL-NEGOTIATOR-004), generalized from one standby to N-1.

Definition in file rte_election.h.