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> --- 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 https://lists.linaro.org/mailman/listinfo/lng-odp