Introduce new APIs that support efficient sharing of portions of
packets:
 * odp_packet_ref_static() creates a new static reference
   for a packet
 * odp_packet_ref() creates a new dynamic reference to a packet
 * odp_packet_ref_pkt() creates a reference to a packet with
   a supplied header packet
 * odp_packet_has_ref() checks if a packet has multiple
   references to it
 * odp_packet_unshared_len() returns the unshared data length of
   a reference

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
Signed-off-by: Bill Fischofer <bill.fischo...@linaro.org>
---
 include/odp/api/spec/packet.h | 133 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 132 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h
index 4a86eba..b891591 100644
--- a/include/odp/api/spec/packet.h
+++ b/include/odp/api/spec/packet.h
@@ -795,7 +795,7 @@ uint32_t odp_packet_seg_data_len(odp_packet_t pkt, 
odp_packet_seg_t seg);
  * data pointers. Otherwise, all old pointers remain valid.
  *
  * The resulting packet is always allocated from the same pool as
- * the destination packet. The source packet may have been allocate from
+ * the destination packet. The source packet may have been allocated from
  * any pool.
  *
  * On failure, both handles remain valid and packets are not modified.
@@ -848,6 +848,137 @@ int odp_packet_split(odp_packet_t *pkt, uint32_t len, 
odp_packet_t *tail);
 
 /*
  *
+ * References
+ * ********************************************************
+ *
+ */
+
+/**
+ * Create a static reference to a packet
+ *
+ * A static reference is used to obtain an additional handle for referring to
+ * the entire packet as it is. As long as a packet has multiple (static)
+ * references, any of the references (including 'pkt') must not be used to
+ * modify the packet in anyway - both data and metadata must remain static.
+ * The packet may be modified again when there is a single reference left.
+ * Static and dynamic references must not be mixed. Results are undefined
+ * if these restrictions are not observed.
+ *
+ * While static references are inflexible they offer efficient way to do e.g.
+ * packet retransmissions. Use odp_packet_ref() or odp_packet_ref_pkt() for
+ * more flexible, dynamic references.
+ *
+ * Packet is not modified on failure.
+ *
+ * @param pkt    Handle of the packet for which a static reference is
+ *               to be created.
+ *
+ * @return Static reference to the packet
+ * @retval ODP_PACKET_INVALID  On failure
+ */
+odp_packet_t odp_packet_ref_static(odp_packet_t pkt);
+
+/**
+ * Create a reference to a packet
+ *
+ * Returns a new (dynamic) reference to a packet starting the shared part of 
the
+ * data at a specified byte offset. Metadata and data before the offset are not
+ * shared with other references of the packet. The rest of the data is shared
+ * and must be treated as read only. Initially the returned reference has
+ * metadata initialized to default values and does not contain unshared data.
+ * Packet (head) manipulation functions may be used normally to e.g. add
+ * a unique header onto the shared payload. The shared part of the packet may 
be
+ * modified again when there is a single reference left. Static and dynamic
+ * references must not be mixed. Results are undefined if these restrictions 
are
+ * not observed.
+ *
+ * The odp_packet_unshared_len() may be used to determine the number of bytes
+ * starting at offset zero that are unique to a packet handle.
+ *
+ * The packet handle 'pkt' may itself by a (dynamic) reference to a packet.
+ *
+ * If the caller does not intend to modify either the packet or the new
+ * reference to it, the odp_packet_ref_static() may be used to create
+ * a static reference that is more optimized for the use case.
+ *
+ * Packet is not modified on failure.
+ *
+ * @param pkt    Handle of the packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in the packet at which the shared part is to
+ *               begin. This must be in the range 0 ... odp_packet_len(pkt)-1.
+ *
+ * @return New reference to the packet
+ * @retval ODP_PACKET_INVALID On failure
+ */
+odp_packet_t odp_packet_ref(odp_packet_t pkt, uint32_t offset);
+
+/**
+ * Create a reference to a packet with a header packet
+ *
+ * This operation is otherwise identical to odp_packet_ref(), but it prepends
+ * a supplied 'hdr' packet as the head of the new reference. The resulting
+ * packet consists metadata and data of the 'hdr' packet, followed by the 
shared
+ * part of packet 'pkt'.
+ *
+ * The packet handle ('pkt') may itself by a (dynamic) reference to a packet,
+ * but the header packet handle ('hdr') must be unique. Both packets must be
+ * have been allocated from the same pool and the handles must not refer to
+ * the same packet. Results are undefined if these restrictions are
+ * not observed.
+ *
+ * Packets are not modified on failure. The header packet 'hdr' is consumed
+ * on success.
+ *
+ * @param pkt    Handle of the packet for which a reference is to be
+ *               created.
+ *
+ * @param offset Byte offset in 'pkt' at which the shared part is to
+ *               begin. Must be in the range 0 ... odp_packet_len(pkt)-1.
+ *
+ * @param hdr    Handle of the header packet to be prefixed onto the new
+ *               reference. Must be a unique reference.
+ *
+ * @return New reference the reference packet
+ * @retval ODP_PACKET_INVALID On failure
+ */
+odp_packet_t odp_packet_ref_pkt(odp_packet_t pkt, uint32_t offset,
+                               odp_packet_t hdr);
+
+/**
+ * Packet unshared data length
+ *
+ * When a packet has multiple references, packet data is divided into
+ * two parts: unshared and shared. The unshared part always precedes
+ * the shared part. This call returns number of bytes in the unshared part.
+ * When a packet has only a single reference, all packet data is unshared and
+ * unshared length equals the packet length (odp_packet_len()).
+ *
+ * Application may modify only the unshared part, the rest of the packet data
+ * must be treated as read only.
+ *
+ * @param pkt  Packet handle
+ *
+ * @return Packet unshared data length
+ */
+uint32_t odp_packet_unshared_len(odp_packet_t pkt);
+
+/**
+ * Test if packet has multiple references
+ *
+ * A packet that has multiple references shares data and possibly metadata with
+ * other packets. Shared part must be treated as read only.
+ *
+ * @param pkt Packet handle
+ *
+ * @retval 0  This is the single reference to the packet
+ * @retval 1  Packet has multiple references
+ */
+int odp_packet_has_ref(odp_packet_t pkt);
+
+/*
+ *
  * Copy
  * ********************************************************
  *
-- 
2.8.1

Reply via email to