Add api for packet reference count support. Which is useful in case:
 - multicast support
 - TCP retransmission
 - traffic generator

Introduced new call: newpkt = odp_packet_create_ref(pkt) which creates
reference to original packet, but handles for reference packet and original
are different.

Signed-off-by: Maxim Uvarov <[email protected]>
---
 include/odp/api/packet.h                             |  9 +++++++++
 platform/linux-generic/include/odp_buffer_internal.h |  2 ++
 platform/linux-generic/odp_packet.c                  | 20 ++++++++++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/include/odp/api/packet.h b/include/odp/api/packet.h
index 5d46b7b..f9745fb 100644
--- a/include/odp/api/packet.h
+++ b/include/odp/api/packet.h
@@ -125,6 +125,15 @@ odp_packet_t odp_packet_from_event(odp_event_t ev);
  */
 odp_event_t odp_packet_to_event(odp_packet_t pkt);
 
+/**
+ * Create reference for packet handle
+ *
+ * @param pkt  Packet handle
+ *
+ * @return New packet handle
+ */
+odp_packet_t odp_packet_create_ref(odp_packet_t pkt);
+
 /*
  *
  * Pointers and lengths
diff --git a/platform/linux-generic/include/odp_buffer_internal.h 
b/platform/linux-generic/include/odp_buffer_internal.h
index 4cacca1..e079c6b 100644
--- a/platform/linux-generic/include/odp_buffer_internal.h
+++ b/platform/linux-generic/include/odp_buffer_internal.h
@@ -79,6 +79,7 @@ typedef union odp_buffer_bits_t {
                uint32_t     u32;
                struct {
 #if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
+                       uint32_t ref:1; /* pkt is reference for other packet */
                        uint32_t pool_id:ODP_BUFFER_POOL_BITS;
                        uint32_t index:ODP_BUFFER_INDEX_BITS;
                        uint32_t seg:ODP_BUFFER_SEG_BITS;
@@ -86,6 +87,7 @@ typedef union odp_buffer_bits_t {
                        uint32_t seg:ODP_BUFFER_SEG_BITS;
                        uint32_t index:ODP_BUFFER_INDEX_BITS;
                        uint32_t pool_id:ODP_BUFFER_POOL_BITS;
+                       uint32_t ref:1; /* pkt is reference for other packet */
 #endif
                };
 
diff --git a/platform/linux-generic/odp_packet.c 
b/platform/linux-generic/odp_packet.c
index 209a6e6..2d5a618 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -49,6 +49,13 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t 
len)
 
 void odp_packet_free(odp_packet_t pkt)
 {
+       odp_buffer_t buf = _odp_packet_to_buffer(pkt);
+       odp_buffer_bits_t handle;
+
+       handle.handle = buf;
+       if (handle.ref)
+               return;
+
        odp_buffer_free((odp_buffer_t)pkt);
 }
 
@@ -85,6 +92,19 @@ odp_event_t odp_packet_to_event(odp_packet_t pkt)
        return (odp_event_t)pkt;
 }
 
+odp_packet_t odp_packet_create_ref(odp_packet_t pkt)
+{
+       odp_buffer_t buf = _odp_packet_to_buffer(pkt);
+       odp_buffer_bits_t handle;
+
+       handle.handle = buf;
+       if (handle.ref)
+               ODP_ABORT("packet is reference already\n");
+       handle.ref = 1;
+
+       return _odp_packet_from_buffer(handle.handle);
+}
+
 /*
  *
  * Pointers and lengths
-- 
1.9.1

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to