174174/// Typically, if block pool allocators are used, the following block sizes should be served:
175175///
176176/// - (MTU+library overhead) blocks for the TX and RX pipelines (usually less than 2048 bytes);
177+ /// - TX fragment item sized blocks for the TX pipeline (less than 128 bytes).
177178/// - RX session object sized blocks for the RX pipeline (less than 512 bytes);
178179/// - RX fragment handle sized blocks for the RX pipeline (less than 128 bytes).
179180///
@@ -373,11 +374,11 @@ struct UdpardMemoryResource
373374// ================================================= TX PIPELINE =================================================
374375// =====================================================================================================================
375376
376- /// The set of memory resources is used per an TX pipeline instance.
377+ /// The set of memory resources is used per a TX pipeline instance.
377378/// These are used to serve the memory needs of the library to keep state while assembling outgoing frames.
378379/// Several memory resources are provided to enable fine control over the allocated memory.
379380///
380- /// This TX queue uses these memory resources for allocating the enqueued items (UDP datagrams).
381+ /// A TX queue uses these memory resources for allocating the enqueued items (UDP datagrams).
381382/// There are exactly two allocations per enqueued item:
382383/// - the first for bookkeeping purposes (UdpardTxItem)
383384/// - second for payload storage (the frame data)
@@ -401,8 +402,6 @@ struct UdpardTxMemoryResources
401402/// Applications that are not interested in transmission may have zero such instances.
402403///
403404/// All operations are logarithmic in complexity on the number of enqueued items.
404- /// There is exactly one memory allocation per element;
405- /// the size of each allocation is sizeof(UdpardTxItem) plus the size of the datagram.
406405///
407406/// Once initialized, instances cannot be copied.
408407///
@@ -461,7 +460,9 @@ struct UdpardTx
461460/// One transport frame (UDP datagram) stored in the UdpardTx transmission queue along with its metadata.
462461/// The datagram should be sent to the indicated UDP/IP endpoint with the specified DSCP value.
463462/// The datagram should be discarded (transmission aborted) if the deadline has expired.
464- /// All fields are READ-ONLY.
463+ /// All fields are READ-ONLY except mutable payload `datagram_payload` field, which could be nullified to indicate
464+ /// a transfer of the payload memory ownership to somewhere else.
465+ ///
465466struct UdpardTxItem
466467{
467468 /// Internal use only; do not access this field.
@@ -568,10 +569,13 @@ int_fast8_t udpardTxInit(struct UdpardTx* const self,
568569/// In such cases, all frames allocated for this transfer (if any) will be deallocated automatically.
569570/// In other words, either all frames of the transfer are enqueued successfully, or none are.
570571///
571- /// The memory allocation requirement is one allocation per datagram:
572- /// a single-frame transfer takes one allocation; a multi-frame transfer of N frames takes N allocations.
573- /// The size of each allocation is (sizeof(UdpardTxItem) + MTU) except for the last datagram where the payload may be
574- /// smaller than the MTU.
572+ /// The memory allocation requirement is two allocations per datagram:
573+ /// a single-frame transfer takes two allocations; a multi-frame transfer of N frames takes N*2 allocations.
574+ /// In each pair of allocations:
575+ /// - the first allocation is for `UdpardTxItem`; the size is `sizeof(UdpardTxItem)`;
576+ /// the TX queue `memory.fragment` memory resource is used for this allocation (and later for deallocation);
577+ /// - the second allocation is for payload storage (the frame data) - size is normally MTU but could be less for
578+ /// the last frame of the transfer; the TX queue `memory.payload` memory resource is used for this allocation.
575579///
576580/// The time complexity is O(p + log e), where p is the amount of payload in the transfer, and e is the number of
577581/// frames already enqueued in the transmission queue.
@@ -641,6 +645,18 @@ int32_t udpardTxRespond(struct UdpardTx* const self,
641645///
642646/// Calling functions that modify the queue may cause the next invocation to return a different pointer.
643647///
648+ /// The payload buffer is allocated in the dynamic storage of the queue. The application may transfer ownership of
649+ /// the payload to a different application component (f.e. to transmission media) by copying the pointer and then
650+ /// (if the ownership transfer was accepted) by nullifying `datagram_payload` fields of the frame (`size` & `data`).
651+ /// If these fields stay with their original values, the `udpardTxFree` (after proper `udpardTxPop` of course) will
652+ /// deallocate the payload buffer. In any case, the payload has to be eventually deallocated by using the TX queue
653+ /// `memory.payload` memory resource. It will be automatically done by the `udpardTxFree` (if the payload still
654+ /// stays in the item), OR if moved, it is the responsibility of the application to eventually (f.e. at the end of
655+ /// transmission) deallocate the memory with the TX queue `memory.payload` memory resource.
656+ /// Note that the mentioned above nullification of the `datagram_payload` fields is the
657+ /// only reason why a returned TX item pointer is mutable. It was constant in the past (before v2),
658+ /// but it was changed to be mutable to allow the payload ownership transfer.
659+ ///
644660/// The time complexity is logarithmic of the queue size. This function does not invoke the dynamic memory manager.
645661struct UdpardTxItem * udpardTxPeek (const struct UdpardTx * const self );
646662
0 commit comments