Skip to content

Commit 4ac88b9

Browse files
Provide deleter per fragment
1 parent 575d5a1 commit 4ac88b9

File tree

1 file changed

+35
-37
lines changed

1 file changed

+35
-37
lines changed

libudpard/udpard.h

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -164,32 +164,6 @@ typedef struct udpard_bytes_t
164164
const void* data;
165165
} udpard_bytes_t;
166166

167-
/// This type represents payload as an ordered sequence of its fragments to eliminate data copying.
168-
/// To free a fragmented payload buffer, the application needs to traverse the list and free each fragment's payload
169-
/// as well as the payload structure itself, assuming that it is also heap-allocated.
170-
/// The model is as follows:
171-
///
172-
/// (payload header) ---> udpard_fragment_t:
173-
/// next ---> udpard_fragment_t...
174-
/// origin ---> (the free()able payload data buffer)
175-
/// view ---> (somewhere inside the payload data buffer)
176-
///
177-
/// Payloads of received transfers are represented using this type, where each fragment corresponds to a frame.
178-
/// The application can either consume them directly or to copy the data into a contiguous buffer beforehand
179-
/// at the expense of extra time and memory utilization.
180-
typedef struct udpard_fragment_t
181-
{
182-
struct udpard_fragment_t* next; ///< Next in the fragmented payload buffer chain; NULL in the last entry.
183-
184-
/// Contains the actual data to be used by the application.
185-
/// The memory pointed to by this fragment shall not be freed by the application.
186-
udpard_bytes_t view;
187-
188-
/// Points to the base buffer that contains this fragment.
189-
/// The application can use this pointer to free the outer buffer after the payload has been consumed.
190-
udpard_bytes_mut_t origin;
191-
} udpard_fragment_t;
192-
193167
/// Zeros if invalid/unset/unavailable.
194168
typedef struct udpard_udpip_ep_t
195169
{
@@ -208,10 +182,6 @@ typedef struct udpard_remote_t
208182
udpard_udpip_ep_t origin[UDPARD_NETWORK_INTERFACE_COUNT_MAX]; ///< Zeros in unavailable ifaces.
209183
} udpard_remote_t;
210184

211-
// =====================================================================================================================
212-
// ================================================= MEMORY RESOURCE =================================================
213-
// =====================================================================================================================
214-
215185
/// The semantics are similar to malloc/free.
216186
/// Consider using O1Heap: https://github.com/pavel-kirienko/o1heap. Alternatively, some applications may prefer to
217187
/// use a set of fixed-size block pool allocators (see the high-level overview for details); for example:
@@ -238,6 +208,38 @@ typedef struct udpard_mem_resource_t
238208
udpard_mem_alloc_t alloc;
239209
} udpard_mem_resource_t;
240210

211+
/// This type represents payload as an ordered sequence of its fragments to eliminate data copying.
212+
/// To free a fragmented payload buffer, the application needs to traverse the list and free each fragment's payload
213+
/// as well as the payload structure itself, assuming that it is also heap-allocated.
214+
/// The model is as follows:
215+
///
216+
/// (payload header) ---> udpard_fragment_t:
217+
/// next ---> udpard_fragment_t...
218+
/// origin ---> (the free()able payload data buffer)
219+
/// view ---> (somewhere inside the payload data buffer)
220+
///
221+
/// Payloads of received transfers are represented using this type, where each fragment corresponds to a frame.
222+
/// The application can either consume them directly or to copy the data into a contiguous buffer beforehand
223+
/// at the expense of extra time and memory utilization.
224+
typedef struct udpard_fragment_t
225+
{
226+
struct udpard_fragment_t* next; ///< Next in the fragmented payload buffer chain; NULL in the last entry.
227+
228+
/// Contains the actual data to be used by the application.
229+
/// The memory pointed to by this fragment shall not be freed by the application.
230+
udpard_bytes_t view;
231+
232+
/// Points to the base buffer that contains this fragment.
233+
/// The application can use this pointer to free the outer buffer after the payload has been consumed.
234+
udpard_bytes_mut_t origin;
235+
236+
/// When the fragment is no longer needed, this deleter shall be used to free the origin buffer.
237+
/// We provide a dedicated deleter per fragment to allow NIC drivers to manage the memory directly,
238+
/// which allows DMA access to the fragment data without copying.
239+
/// See https://github.com/OpenCyphal-Garage/libcyphal/issues/352#issuecomment-2163056622
240+
udpard_mem_deleter_t payload_deleter;
241+
} udpard_fragment_t;
242+
241243
// =====================================================================================================================
242244
// ================================================= TX PIPELINE =================================================
243245
// =====================================================================================================================
@@ -460,12 +462,6 @@ typedef struct udpard_rx_memory_resources_t
460462
/// The fragment handles are allocated per payload fragment; each handle contains a pointer to its fragment.
461463
/// Each instance is of a very small fixed size, so a trivial zero-fragmentation block allocator is sufficient.
462464
udpard_mem_resource_t fragment;
463-
464-
/// The library never allocates payload buffers itself, as they are handed over by the application via
465-
/// udpard_rx_...(). Once a buffer is handed over, the library may choose to keep it if it is deemed to be
466-
/// necessary to complete a transfer reassembly, or to discard it if it is deemed to be unnecessary.
467-
/// Discarded payload buffers are freed using this resource.
468-
udpard_mem_deleter_t payload;
469465
} udpard_rx_memory_resources_t;
470466

471467
/// This type represents an open input port, such as a subscription to a topic.
@@ -569,7 +565,7 @@ typedef struct udpard_rx_transfer_t
569565
/// Emitted when the stack detects the need to send a reception acknowledgment back to the remote node.
570566
typedef struct udpard_rx_ack_mandate_t
571567
{
572-
udpard_remote_t origin;
568+
udpard_remote_t remote;
573569
udpard_prio_t priority;
574570
uint64_t transfer_id;
575571
udpard_bytes_t payload_head; ///< View of the first <=MTU bytes of the transfer payload that is being confirmed.
@@ -699,13 +695,15 @@ bool udpard_rx_subscription_receive(udpard_rx_t* const rx,
699695
const udpard_microsecond_t timestamp_usec,
700696
const udpard_udpip_ep_t source_endpoint,
701697
const udpard_bytes_mut_t datagram_payload,
698+
const udpard_mem_deleter_t payload_deleter,
702699
const uint_fast8_t redundant_iface_index);
703700

704701
/// Like the above but for P2P unicast transfers exchanged between specific nodes.
705702
bool udpard_rx_p2p_receive(udpard_rx_subscription_t* const rx,
706703
const udpard_microsecond_t timestamp_usec,
707704
const udpard_udpip_ep_t source_endpoint,
708705
const udpard_bytes_mut_t datagram_payload,
706+
const udpard_mem_deleter_t payload_deleter,
709707
const uint_fast8_t redundant_iface_index);
710708

711709
#ifdef __cplusplus

0 commit comments

Comments
 (0)