Usage and implementation are simpler without the wait parameter. I think it’s 
better to keep these two versions separate: one that never calls any system 
calls, and one that may use system calls to check time and sleep. The no_wait 
option is handy if application needs to swap between wait X nsec and no_wait.

-Petri


From: EXT Bala Manoharan [mailto:bala.manoha...@linaro.org]
Sent: Thursday, March 17, 2016 4:32 PM
To: Savolainen, Petri (Nokia - FI/Espoo) <petri.savolai...@nokia.com>
Cc: LNG ODP Mailman List <lng-odp@lists.linaro.org>
Subject: Re: [lng-odp] [API-NEXT PATCH] api: pktio: add odp_pktin_recv_tmo

Hi,

odp_pktin_recv_tmo() function called with wait value equal to ODP_PKTIN_NO_WAIT 
is similar to odp_pktin_recv() function. Hence why cant we simply merge these 
two functions as a single one. odp_pktin_recv() functions looks redundant.

Regards,
Bala

On 17 March 2016 at 19:37, Petri Savolainen 
<petri.savolai...@nokia.com<mailto:petri.savolai...@nokia.com>> wrote:
Added single queue recv function with timeout. In a simple
configuration each thread polls a single input queue. Timeout
version of single queue receive allows thread to sleep when
there are no packets. odp_pktin_recv_mq_tmo would be unnecessary
complex to use for single input queue.

Signed-off-by: Petri Savolainen 
<petri.savolai...@nokia.com<mailto:petri.savolai...@nokia.com>>
---
 include/odp/api/spec/packet_io.h       | 36 ++++++++++++++++++++++---
 platform/linux-generic/odp_packet_io.c | 49 +++++++++++++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h
index 6fe2cac..1860b31 100644
--- a/include/odp/api/spec/packet_io.h
+++ b/include/odp/api/spec/packet_io.h
@@ -522,8 +522,10 @@ odp_pktio_t odp_pktio_lookup(const char *name);
 /**
  * Receive packets directly from an interface input queue
  *
- * Receives up to 'num' packets from the pktio interface input queue. When
- * input queue parameter 'op_mode' has been set to ODP_PKTIO_OP_MT_UNSAFE,
+ * Receives up to 'num' packets from the pktio interface input queue. Returns
+ * the number of packets received.
+ *
+ * When input queue parameter 'op_mode' has been set to ODP_PKTIO_OP_MT_UNSAFE,
  * the operation is optimized for single thread operation per queue and the 
same
  * queue must not be accessed simultaneously from multiple threads.
  *
@@ -539,7 +541,35 @@ odp_pktio_t odp_pktio_lookup(const char *name);
 int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num);

 /**
- * Receive packets directly from multiple interface input queues
+ * Receive packets directly from an interface input queue with timeout
+ *
+ * Receives up to 'num' packets from the pktio interface input queue. If there
+ * are no packets available, waits for packets depeding on 'wait' parameter
+ * value. Returns the number of packets received.
+ *
+ * When input queue parameter 'op_mode' has been set to ODP_PKTIO_OP_MT_UNSAFE,
+ * the operation is optimized for single thread operation per queue and the 
same
+ * queue must not be accessed simultaneously from multiple threads.
+ *
+ * @param      queue      Packet input queue handle for receiving packets
+ * @param[out] packets[]  Packet handle array for output of received packets
+ * @param      num        Maximum number of packets to receive
+ * @param      wait       Wait time specified as as follows:
+ *                        * ODP_PKTIN_NO_WAIT: Do not wait
+ *                        * ODP_PKTIN_WAIT:    Wait infinitely
+ *                        * Other values specify the minimum time to wait.
+ *                          Use odp_pktin_wait_time() to convert nanoseconds
+ *                          to a valid parameter value. Wait time may be
+ *                          rounded up a small, platform specific amount.
+ *
+ * @return Number of packets received
+ * @retval <0 on failure
+ */
+int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[],
+                      int num, uint64_t wait);
+
+/**
+ * Receive packets directly from multiple interface input queues with timeout
  *
  * Receives up to 'num' packets from one of the specified pktio interface input
  * queues. The index of the source queue is stored into 'from' output
diff --git a/platform/linux-generic/odp_packet_io.c 
b/platform/linux-generic/odp_packet_io.c
index aafb3d9..948baa8 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -21,6 +21,7 @@
 #include <odp_classification_internal.h>
 #include <odp_debug_internal.h>
 #include <odp_packet_io_ipc_internal.h>
+#include <odp/api/time.h>

 #include <string.h>
 #include <sys/ioctl.h>
@@ -28,7 +29,12 @@
 #include <errno.h>
 #include <time.h>

-#define SLEEP_NSEC 1000
+/* Sleep this many nanoseconds between pktin receive calls */
+#define SLEEP_NSEC  1000
+
+/* Check total sleep time about every SLEEP_CHECK * SLEEP_NSEC nanoseconds.
+ * Must be power of two. */
+#define SLEEP_CHECK 32

 pktio_table_t *pktio_tbl;

@@ -1387,6 +1393,47 @@ int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t 
packets[], int num)
        return single_recv_queue(entry, queue.index, packets, num);
 }

+int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], int 
num,
+                      uint64_t wait)
+{
+       int ret;
+       odp_time_t t1, t2;
+       struct timespec ts;
+
+       if (wait != ODP_PKTIN_WAIT) {
+               ts.tv_sec  = 0;
+               ts.tv_nsec = SLEEP_NSEC;
+
+               t1 = odp_time_sum(odp_time_local(),
+                                 odp_time_local_from_ns(wait * SLEEP_NSEC));
+       }
+
+       while (1) {
+               ret = odp_pktin_recv(queue, packets, num);
+
+               if (ret != 0)
+                       return ret;
+
+               if (wait == 0)
+                       return 0;
+
+               if (wait != ODP_PKTIN_WAIT) {
+                       wait--;
+
+                       /* check every SLEEP_CHECK rounds if total wait time
+                        * has been exceeded. */
+                       if ((wait & SLEEP_CHECK) == 0) {
+                               t2 = odp_time_local();
+
+                               if (odp_time_cmp(t2, t1) > 0)
+                                       return 0;
+                       }
+               }
+
+               nanosleep(&ts, NULL);
+       }
+}
+
 int odp_pktin_recv_mq_tmo(const odp_pktin_queue_t queues[], unsigned num_q,
                          unsigned *from, odp_packet_t packets[], int num,
                          uint64_t wait)
--
2.7.2

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org<mailto:lng-odp@lists.linaro.org>
https://lists.linaro.org/mailman/listinfo/lng-odp

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to