Skip to content

Commit 666033e

Browse files
cleanup
1 parent 50af135 commit 666033e

2 files changed

Lines changed: 40 additions & 41 deletions

File tree

libudpard/udpard.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -588,11 +588,10 @@ typedef struct tx_transfer_t
588588
/// The transmission iface set is indicated by which head[] entries are non-NULL.
589589
tx_frame_t* head[UDPARD_IFACE_COUNT_MAX];
590590
tx_frame_t* cursor[UDPARD_IFACE_COUNT_MAX];
591-
uint32_t epoch : 8; ///< Does not overflow due to exponential backoff; e.g. 1us with epoch=48 => 9 years.
592591

593592
/// Constant transfer properties supplied by the client.
594-
uint32_t priority : 3;
595593
void* user;
594+
udpard_prio_t priority;
596595
udpard_us_t deadline;
597596
udpard_udpip_ep_t endpoints[UDPARD_IFACE_COUNT_MAX];
598597
} tx_transfer_t;
@@ -786,13 +785,14 @@ static bool tx_push(udpard_tx_t* const tx,
786785
const udpard_us_t now,
787786
const udpard_us_t deadline,
788787
const meta_t meta,
789-
const uint16_t iface_bitmap,
790788
const udpard_udpip_ep_t endpoints[UDPARD_IFACE_COUNT_MAX],
791789
const udpard_bytes_scattered_t payload,
792790
void* const user)
793791
{
794792
UDPARD_ASSERT(now <= deadline);
795793
UDPARD_ASSERT(tx != NULL);
794+
795+
const uint16_t iface_bitmap = valid_ep_bitmap(endpoints);
796796
UDPARD_ASSERT((iface_bitmap & UDPARD_IFACE_BITMAP_ALL) != 0);
797797
UDPARD_ASSERT((iface_bitmap & UDPARD_IFACE_BITMAP_ALL) == iface_bitmap);
798798

@@ -806,10 +806,9 @@ static bool tx_push(udpard_tx_t* const tx,
806806
return false;
807807
}
808808
mem_zero(sizeof(*tr), tr);
809-
tr->epoch = 0;
810-
tr->priority = ((byte_t)meta.priority) & UDPARD_PRIORITY_MASK;
811-
tr->deadline = deadline;
812809
tr->user = user;
810+
tr->priority = meta.priority;
811+
tr->deadline = deadline;
813812
for (size_t i = 0; i < UDPARD_IFACE_COUNT_MAX; i++) {
814813
tr->head[i] = tr->cursor[i] = NULL;
815814
tr->endpoints[i] = endpoints[i];
@@ -907,7 +906,6 @@ bool udpard_tx_new(udpard_tx_t* const self,
907906
self->p2p_transfer_id = p2p_transfer_id_seed + local_uid; // extra entropy
908907
self->enqueued_frames_limit = enqueued_frames_limit;
909908
self->enqueued_frames_count = 0;
910-
self->next_seq_no = 0;
911909
self->memory = memory;
912910
self->index_deadline = NULL;
913911
self->agewise = (udpard_list_t){ NULL, NULL };
@@ -929,18 +927,27 @@ bool udpard_tx_push(udpard_tx_t* const self,
929927
const uint16_t iface_bitmap,
930928
const udpard_prio_t priority,
931929
const uint64_t transfer_id,
930+
const udpard_udpip_ep_t endpoint,
932931
const udpard_bytes_scattered_t payload,
933932
void* const user)
934933
{
935934
bool ok = (self != NULL) && (deadline >= now) && (now >= 0) && (self->local_uid != 0) &&
936935
((iface_bitmap & UDPARD_IFACE_BITMAP_ALL) != 0) && (priority < UDPARD_PRIORITY_COUNT) &&
937-
((payload.bytes.data != NULL) || (payload.bytes.size == 0U));
936+
udpard_is_valid_endpoint(endpoint) && ((payload.bytes.data != NULL) || (payload.bytes.size == 0U));
938937
if (ok) {
939-
const meta_t meta = { .priority = priority,
940-
.transfer_payload_size = (uint32_t)bytes_scattered_size(payload),
941-
.transfer_id = transfer_id,
942-
.sender_uid = self->local_uid };
943-
ok = tx_push(self, now, deadline, meta, iface_bitmap & UDPARD_IFACE_BITMAP_ALL, NULL, payload, user);
938+
const meta_t meta = {
939+
.priority = priority,
940+
.transfer_payload_size = (uint32_t)bytes_scattered_size(payload),
941+
.transfer_id = transfer_id,
942+
.sender_uid = self->local_uid,
943+
};
944+
udpard_udpip_ep_t eps[UDPARD_IFACE_COUNT_MAX] = { 0 };
945+
for (size_t i = 0; i < UDPARD_IFACE_COUNT_MAX; i++) {
946+
if ((iface_bitmap & (1U << i)) != 0) {
947+
eps[i] = endpoint;
948+
}
949+
}
950+
ok = tx_push(self, now, deadline, meta, eps, payload, user);
944951
}
945952
return ok;
946953
}
@@ -953,15 +960,17 @@ bool udpard_tx_push_p2p(udpard_tx_t* const self,
953960
const udpard_bytes_scattered_t payload,
954961
void* const user)
955962
{
956-
const uint16_t iface_bitmap = valid_ep_bitmap(endpoints);
957-
bool ok = (self != NULL) && (deadline >= now) && (now >= 0) && (self->local_uid != 0) && (iface_bitmap != 0) &&
958-
(priority < UDPARD_PRIORITY_COUNT) && ((payload.bytes.data != NULL) || (payload.bytes.size == 0U));
963+
bool ok = (self != NULL) && (deadline >= now) && (now >= 0) && (self->local_uid != 0) &&
964+
(valid_ep_bitmap(endpoints) != 0) && (priority < UDPARD_PRIORITY_COUNT) &&
965+
((payload.bytes.data != NULL) || (payload.bytes.size == 0U));
959966
if (ok) {
960-
const meta_t meta = { .priority = priority,
961-
.transfer_payload_size = (uint32_t)bytes_scattered_size(payload),
962-
.transfer_id = self->p2p_transfer_id++,
963-
.sender_uid = self->local_uid };
964-
ok = tx_push(self, now, deadline, meta, iface_bitmap, endpoints, payload, user); // --------------
967+
const meta_t meta = {
968+
.priority = priority,
969+
.transfer_payload_size = (uint32_t)bytes_scattered_size(payload),
970+
.transfer_id = self->p2p_transfer_id++,
971+
.sender_uid = self->local_uid,
972+
};
973+
ok = tx_push(self, now, deadline, meta, endpoints, payload, user);
965974
}
966975
return ok;
967976
}
@@ -993,6 +1002,7 @@ static void tx_eject_pending_frames(udpard_tx_t* const self, const udpard_us_t n
9931002
{
9941003
udpard_tx_ejection_t ejection = { .now = now,
9951004
.deadline = tr->deadline,
1005+
.destination = tr->endpoints[ifindex],
9961006
.iface_index = ifindex,
9971007
.dscp = self->dscp_value_per_priority[tr->priority],
9981008
.datagram = tx_frame_view(frame),

libudpard/udpard.h

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ typedef enum udpard_prio_t
106106
udpard_prio_optional = 7,
107107
} udpard_prio_t;
108108
#define UDPARD_PRIORITY_COUNT 8U
109-
#define UDPARD_PRIORITY_MASK (UDPARD_PRIORITY_COUNT - 1U)
110109

111110
typedef struct udpard_tree_t
112111
{
@@ -145,11 +144,6 @@ typedef struct udpard_bytes_mut_t
145144
void* data;
146145
} udpard_bytes_mut_t;
147146

148-
/// The size can be changed arbitrarily. This value is a compromise between copy size and footprint and utility.
149-
#ifndef UDPARD_USER_CONTEXT_PTR_COUNT
150-
#define UDPARD_USER_CONTEXT_PTR_COUNT 2
151-
#endif
152-
153147
/// Zeros if invalid/unset/unavailable.
154148
typedef struct udpard_udpip_ep_t
155149
{
@@ -176,8 +170,7 @@ typedef struct udpard_remote_t
176170
bool udpard_is_valid_endpoint(const udpard_udpip_ep_t ep);
177171

178172
/// Returns the destination multicast UDP/IP endpoint for the given subject-ID.
179-
/// The application should use this function when setting up subscription sockets or sending datagrams in
180-
/// udpard_tx_vtable_t::eject_subject().
173+
/// The application should use this function when setting up subscription sockets or sending datagrams.
181174
/// If the subject-ID exceeds UDPARD_IPv4_SUBJECT_ID_MAX, the excessive bits are masked out.
182175
/// For P2P use the unicast node address directly instead, as provided by the RX pipeline per received transfer.
183176
udpard_udpip_ep_t udpard_make_subject_endpoint(const uint32_t subject_id);
@@ -337,7 +330,7 @@ typedef struct udpard_tx_vtable_t
337330
/// Invoked from udpard_tx_poll() to push outgoing UDP datagrams into the socket/NIC driver.
338331
/// It is GUARANTEED that ONLY udpard_tx_poll() can invoke this function; in particular, pushing new transfers
339332
/// will not trigger ejection callbacks.
340-
/// The callback must not mutate the TX pipeline (no udpard_tx_push/cancel/free).
333+
/// The callback must not mutate the TX pipeline (no udpard_tx_push/free).
341334
bool (*eject)(udpard_tx_t*, udpard_tx_ejection_t*);
342335
} udpard_tx_vtable_t;
343336

@@ -378,10 +371,6 @@ struct udpard_tx_t
378371
/// READ-ONLY!
379372
size_t enqueued_frames_count;
380373

381-
/// Starts at zero and increments with every enqueued transfer. Do not modify!
382-
/// This is used internally as a tiebreaker in non-unique indexes.
383-
uint64_t next_seq_no;
384-
385374
udpard_tx_mem_resources_t memory;
386375

387376
/// Error counters incremented automatically when the corresponding error condition occurs.
@@ -426,24 +415,23 @@ bool udpard_tx_new(udpard_tx_t* const self,
426415
/// invalidated immediately after this function returns. When redundant interfaces are used, the library will attempt to
427416
/// minimize the number of copies by reusing frames across interfaces with identical MTU values and memory resources.
428417
///
418+
/// The endpoint depends on the subject-ID and is computed using udpard_make_subject_endpoint().
419+
/// The endpoint must satisfy udpard_is_valid_endpoint().
420+
///
429421
/// The caller shall increment the transfer-ID counter after each successful invocation of this function per subject.
430422
/// The initial value shall be chosen randomly such that it is likely to be distinct per application startup
431423
/// (embedded systems can use noinit memory sections, hash uninitialized SRAM, use timers or ADC noise, etc).
432424
/// The random starting point will ensure global uniqueness across different subjects.
433425
/// Excess most significant bits are ignored.
434426
/// Related thread on random transfer-ID init: https://forum.opencyphal.org/t/improve-the-transfer-id-timeout/2375
435427
///
436-
/// The user context value is carried through to the callbacks. It must contain enough context to allow subject-ID
437-
/// derivation inside udpard_tx_vtable_t::eject_subject(). For example, it may contain a pointer to the topic struct.
428+
/// The enqueued transfer will be emitted over all interfaces specified in the iface_bitmap.
429+
///
430+
/// The user context value is carried through to the callbacks.
438431
///
439432
/// Returns true on success. Runtime failures increment the corresponding error counters,
440433
/// while invocations with invalid arguments just return zero without modifying the queue state.
441434
///
442-
/// The enqueued transfer will be emitted over all interfaces specified in the iface_bitmap.
443-
/// The subject-ID is computed inside the udpard_tx_vtable::eject_subject() callback at the time of transmission.
444-
/// The subject-ID cannot be computed beforehand at the time of enqueuing because the topic->subject consensus protocol
445-
/// may find a different subject-ID allocation between the time of enqueuing and the time of (re)transmission.
446-
///
447435
/// On success, the function allocates a single transfer state instance and a number of payload fragments.
448436
/// The time complexity is O(p + log e), where p is the transfer payload size, and e is the number of
449437
/// transfers already enqueued in the transmission queue.
@@ -453,6 +441,7 @@ bool udpard_tx_push(udpard_tx_t* const self,
453441
const uint16_t iface_bitmap,
454442
const udpard_prio_t priority,
455443
const uint64_t transfer_id,
444+
const udpard_udpip_ep_t endpoint,
456445
const udpard_bytes_scattered_t payload,
457446
void* const user);
458447

0 commit comments

Comments
 (0)