@@ -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.
194168typedef 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.
570566typedef 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.
705702bool 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