15 const void *a,
const void *b,
size_t size)
19 if (cmp->config.
compare != NULL)
25 equal = (memcmp(a, b, size) == 0);
35 if ((storage == NULL) || (config == NULL))
44 return lifecycle_status;
47 storage->config = *config;
48 storage->channel_a = NULL;
49 storage->channel_b = NULL;
50 storage->registered_count = 0U;
51 storage->total_disagreements = 0U;
52 storage->initialized =
true;
62 if ((cmp == NULL) || (channel == NULL))
66 if (!cmp->initialized)
76 return lifecycle_status;
79 if (cmp->registered_count == 0U)
81 cmp->channel_a = channel;
82 cmp->registered_count = 1U;
84 else if (cmp->registered_count == 1U)
86 cmp->channel_b = channel;
87 cmp->registered_count = 2U;
103 const void *agreed_data,
size_t data_size,
108 *result = local_result;
113 if (out_data != NULL)
115 (void)memcpy(out_data, agreed_data, data_size);
117 if (out_size != NULL)
119 *out_size = data_size;
124 if (out_size != NULL)
131 cmp->total_disagreements++;
166 void *out_data,
size_t *out_size)
173 if ((cmp == NULL) || (data_size == 0U))
177 if (!cmp->initialized)
185 if (cmp->registered_count != 2U)
211 else if (cross_comparator_data_equal(cmp, buf_a, buf_b, data_size))
225 const void *local_data,
const void *peer_data,
228 void *out_data,
size_t *out_size)
232 if ((cmp == NULL) || (local_data == NULL) || (peer_data == NULL) || (data_size == 0U))
236 if (!cmp->initialized)
245 local_result = cross_comparator_data_equal(cmp, local_data, peer_data, data_size) ?
RTE_VOTING_AGREED
252 uint32_t *healthy_count,
253 uint32_t *total_disagreements)
264 if (cmp->registered_count >= 1U)
272 if (cmp->registered_count >= 2U)
281 if (healthy_count != NULL)
283 *healthy_count = healthy;
285 if (total_disagreements != NULL)
287 *total_disagreements = cmp->total_disagreements;
298 cmp->initialized =
false;
rte_status_t rte_lifecycle_check_setup_allowed(void)
Convenience check for a setup-only constructor: call this as one of the first checks in any function ...
void rte_log_write(rte_log_level_t level, const char *tag, const char *message)
Emits one log message. Non-blocking; never fails the caller's control flow even if the message is dro...
#define RTE_SAFESTATE(level, reason)
Explicitly enters the given safe-state level with a reason code, capturing the call site automaticall...
rte_status_t
Common result/status codes.
@ RTE_STATUS_INVALID_PARAM
@ RTE_STATUS_NOT_INITIALIZED
@ RTE_STATUS_HARDWARE_FAULT
@ RTE_STATUS_RESOURCE_EXHAUSTED
rte_status_t rte_channel_receive(rte_channel_t *handle, void *data, size_t data_size, uint32_t timeout_ms)
Receives data on this channel via its OSAdapter receive callback.
rte_status_t rte_channel_get_health(const rte_channel_t *handle, rte_channel_health_t *out_health)
Queries this channel's health statistics.
rte_channel_storage_t rte_channel_t
Opaque handle to a vital channel instance.
rte_status_t rte_cross_comparator_register_channel(rte_cross_comparator_t *cmp, rte_channel_t *channel)
Registers one already-initialized channel (channel A, then B).
rte_status_t rte_cross_comparator_execute(rte_cross_comparator_t *cmp, size_t data_size, rte_voting_result_t *result, void *out_data, size_t *out_size)
Receives from both registered channels and compares them.
rte_status_t rte_cross_comparator_init(rte_cross_comparator_storage_t *storage, const rte_cross_comparator_config_t *config)
Initializes a cross-comparator with zero registered channels.
rte_cross_comparator_storage_t rte_cross_comparator_t
Opaque handle to a cross-comparator instance.
#define RTE_CROSS_COMPARATOR_MAX_MESSAGE_SIZE
Maximum payload size rte_cross_comparator_execute() supports.
rte_status_t rte_cross_comparator_get_aggregated_health(const rte_cross_comparator_t *cmp, uint32_t *healthy_count, uint32_t *total_disagreements)
Aggregated health across both registered channels.
rte_status_t rte_cross_comparator_execute_buffers(rte_cross_comparator_t *cmp, const void *local_data, const void *peer_data, size_t data_size, rte_voting_result_t *result, void *out_data, size_t *out_size)
Compares two already-in-hand data buffers directly, with the same on_disagreement-then-unconditional-...
rte_status_t rte_cross_comparator_destroy(rte_cross_comparator_t *cmp)
Destroys a cross-comparator instance.
rte_voting_result_t
Outcome of one rte_voter_receive() call.
@ RTE_VOTING_INSUFFICIENT_QUORUM
static rte_status_t cross_comparator_finish(rte_cross_comparator_t *cmp, rte_voting_result_t local_result, const void *agreed_data, size_t data_size, rte_voting_result_t *result, void *out_data, size_t *out_size)
Pairwise comparison between exactly 2 registered rte_channel_t links (ADR-025).
Process-wide application setup-phase lock (ADR-026).
OS Abstraction Layer - Logging/diagnostics service.
Safe-state transitions and checked assertions (ADR-004).
Health statistics for one vital channel.
Configuration for rte_cross_comparator_init().
uint32_t channel_timeout_ms
rte_safestate_reason_t safestate_reason
void * disagreement_context
rte_voter_compare_fn compare
void(*) on_disagreement(void *context, rte_voting_result_t result)
rte_safestate_level_t safestate_level
Storage for one cross-comparator instance (opaque to caller). No dynamic memory.