Skip to content

Commit e8469fd

Browse files
committed
Eliminate private TxItem
1 parent 36a5aec commit e8469fd

File tree

3 files changed

+171
-207
lines changed

3 files changed

+171
-207
lines changed

libudpard/udpard.c

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -272,23 +272,12 @@ static inline uint32_t transferCRCCompute(const size_t size, const void* const d
272272
// ================================================= TX PIPELINE =================================================
273273
// =====================================================================================================================
274274

275-
/// This is a subclass of UdpardTxItem. A pointer to this type can be cast to UdpardTxItem safely.
276-
/// This is compliant with the C99 standard; paragraph 6.7.2.1.15 says:
277-
/// A pointer to a structure object, suitably converted, points to its initial member (or if that member is a
278-
/// bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a
279-
/// structure object, but not at its beginning.
280-
typedef struct
281-
{
282-
struct UdpardTxItem base;
283-
enum UdpardPriority priority; ///< Do we need this exposed in the public structure? We already have DSCP there.
284-
} TxItem;
285-
286275
/// Chain of TX frames prepared for insertion into a TX queue.
287276
typedef struct
288277
{
289-
TxItem* head;
290-
TxItem* tail;
291-
size_t count;
278+
struct UdpardTxItem* head;
279+
struct UdpardTxItem* tail;
280+
size_t count;
292281
} TxChain;
293282

294283
static inline bool txValidateMemoryResources(const struct UdpardTxMemoryResources memory)
@@ -297,40 +286,40 @@ static inline bool txValidateMemoryResources(const struct UdpardTxMemoryResource
297286
(memory.payload.allocate != NULL) && (memory.payload.deallocate != NULL);
298287
}
299288

300-
static inline TxItem* txNewItem(const struct UdpardTxMemoryResources memory,
301-
const uint_least8_t dscp_value_per_priority[UDPARD_PRIORITY_MAX + 1U],
302-
const UdpardMicrosecond deadline_usec,
303-
const enum UdpardPriority priority,
304-
const struct UdpardUDPIPEndpoint endpoint,
305-
const size_t datagram_payload_size,
306-
void* const user_transfer_reference)
289+
static inline struct UdpardTxItem* txNewItem(const struct UdpardTxMemoryResources memory,
290+
const uint_least8_t dscp_value_per_priority[UDPARD_PRIORITY_MAX + 1U],
291+
const UdpardMicrosecond deadline_usec,
292+
const enum UdpardPriority priority,
293+
const struct UdpardUDPIPEndpoint endpoint,
294+
const size_t datagram_payload_size,
295+
void* const user_transfer_reference)
307296
{
308-
TxItem* out = memAlloc(memory.fragment, sizeof(TxItem));
297+
struct UdpardTxItem* out = memAlloc(memory.fragment, sizeof(struct UdpardTxItem));
309298
if (out != NULL)
310299
{
311300
// No tree linkage by default.
312-
out->base.base.up = NULL;
313-
out->base.base.lr[0] = NULL;
314-
out->base.base.lr[1] = NULL;
315-
out->base.base.bf = 0;
301+
out->base.up = NULL;
302+
out->base.lr[0] = NULL;
303+
out->base.lr[1] = NULL;
304+
out->base.bf = 0;
316305
// Init metadata.
317-
out->priority = priority;
318-
out->base.next_in_transfer = NULL; // Last by default.
319-
out->base.deadline_usec = deadline_usec;
306+
out->priority = priority;
307+
out->next_in_transfer = NULL; // Last by default.
308+
out->deadline_usec = deadline_usec;
320309
UDPARD_ASSERT(priority <= UDPARD_PRIORITY_MAX);
321-
out->base.dscp = dscp_value_per_priority[priority];
322-
out->base.destination = endpoint;
323-
out->base.user_transfer_reference = user_transfer_reference;
310+
out->dscp = dscp_value_per_priority[priority];
311+
out->destination = endpoint;
312+
out->user_transfer_reference = user_transfer_reference;
324313

325314
void* const payload_data = memAlloc(memory.payload, datagram_payload_size);
326315
if (NULL != payload_data)
327316
{
328-
out->base.datagram_payload.data = payload_data;
329-
out->base.datagram_payload.size = datagram_payload_size;
317+
out->datagram_payload.data = payload_data;
318+
out->datagram_payload.size = datagram_payload_size;
330319
}
331320
else
332321
{
333-
memFree(memory.fragment, sizeof(TxItem), out);
322+
memFree(memory.fragment, sizeof(struct UdpardTxItem), out);
334323
out = NULL;
335324
}
336325
}
@@ -342,8 +331,8 @@ static inline TxItem* txNewItem(const struct UdpardTxMemoryResources memory,
342331
static inline int_fast8_t txAVLPredicate(void* const user_reference, // NOSONAR Cavl API requires pointer to non-const.
343332
const struct UdpardTreeNode* const node)
344333
{
345-
const TxItem* const target = (const TxItem*) user_reference;
346-
const TxItem* const other = (const TxItem*) (const void*) node;
334+
const struct UdpardTxItem* const target = (const struct UdpardTxItem*) user_reference;
335+
const struct UdpardTxItem* const other = (const struct UdpardTxItem*) (const void*) node;
347336
UDPARD_ASSERT((target != NULL) && (other != NULL));
348337
return (target->priority >= other->priority) ? +1 : -1;
349338
}
@@ -421,13 +410,13 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory,
421410
size_t offset = 0U;
422411
while (offset < payload_size_with_crc)
423412
{
424-
TxItem* const item = txNewItem(memory,
425-
dscp_value_per_priority,
426-
deadline_usec,
427-
meta.priority,
428-
endpoint,
429-
smaller(payload_size_with_crc - offset, mtu) + HEADER_SIZE_BYTES,
430-
user_transfer_reference);
413+
struct UdpardTxItem* const item = txNewItem(memory,
414+
dscp_value_per_priority,
415+
deadline_usec,
416+
meta.priority,
417+
endpoint,
418+
smaller(payload_size_with_crc - offset, mtu) + HEADER_SIZE_BYTES,
419+
user_transfer_reference);
431420
if (NULL == out.head)
432421
{
433422
out.head = item;
@@ -436,15 +425,15 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory,
436425
{
437426
// C std, 6.7.2.1.15: A pointer to a structure object <...> points to its initial member, and vice versa.
438427
// Can't just read tqi->base because tqi may be NULL; https://github.com/OpenCyphal/libcanard/issues/203.
439-
out.tail->base.next_in_transfer = (struct UdpardTxItem*) item;
428+
out.tail->next_in_transfer = item;
440429
}
441430
out.tail = item;
442431
if (NULL == out.tail)
443432
{
444433
break;
445434
}
446435
const bool last = (payload_size_with_crc - offset) <= mtu;
447-
byte_t* const dst_buffer = item->base.datagram_payload.data;
436+
byte_t* const dst_buffer = item->datagram_payload.data;
448437
byte_t* write_ptr = txSerializeHeader(dst_buffer, meta, (uint32_t) out.count, last);
449438
if (offset < payload.size)
450439
{
@@ -460,7 +449,7 @@ static inline TxChain txMakeChain(const struct UdpardTxMemoryResources memory,
460449
{
461450
const size_t crc_offset = offset - payload.size;
462451
UDPARD_ASSERT(crc_offset < TRANSFER_CRC_SIZE_BYTES);
463-
const size_t available = item->base.datagram_payload.size - (size_t) (write_ptr - dst_buffer);
452+
const size_t available = item->datagram_payload.size - (size_t) (write_ptr - dst_buffer);
464453
UDPARD_ASSERT(available <= TRANSFER_CRC_SIZE_BYTES);
465454
const size_t write_size = smaller(TRANSFER_CRC_SIZE_BYTES - crc_offset, available);
466455
// NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
@@ -509,7 +498,7 @@ static inline int32_t txPush(struct UdpardTx* const tx,
509498
if (chain.tail != NULL)
510499
{
511500
UDPARD_ASSERT(frame_count == chain.count);
512-
struct UdpardTxItem* next = &chain.head->base;
501+
struct UdpardTxItem* next = chain.head;
513502
do
514503
{
515504
const struct UdpardTreeNode* const res =
@@ -527,7 +516,7 @@ static inline int32_t txPush(struct UdpardTx* const tx,
527516
else // The queue is large enough but we ran out of heap memory, so we have to unwind the chain.
528517
{
529518
out = -UDPARD_ERROR_MEMORY;
530-
struct UdpardTxItem* head = &chain.head->base;
519+
struct UdpardTxItem* head = chain.head;
531520
while (head != NULL)
532521
{
533522
struct UdpardTxItem* const next = head->next_in_transfer;
@@ -694,7 +683,7 @@ void udpardTxFree(const struct UdpardTxMemoryResources memory, struct UdpardTxIt
694683
memFree(memory.payload, item->datagram_payload.size, item->datagram_payload.data);
695684
}
696685

697-
memFree(memory.fragment, sizeof(TxItem), item);
686+
memFree(memory.fragment, sizeof(struct UdpardTxItem), item);
698687
}
699688
}
700689

libudpard/udpard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ struct UdpardTxItem
482482
/// LibUDPard selects the DSCP value based on the transfer priority level and the configured DSCP mapping.
483483
uint_least8_t dscp;
484484

485+
/// Holds original transfer priority level (before DSCP mapping, see above `dscp`).
486+
enum UdpardPriority priority;
487+
485488
/// This UDP/IP datagram compiled by libudpard should be sent to this endpoint.
486489
/// The endpoint is always at a multicast address.
487490
struct UdpardUDPIPEndpoint destination;

0 commit comments

Comments
 (0)