diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/README | 2 | ||||
-rw-r--r-- | test/example/Makefile.am | 5 | ||||
-rw-r--r-- | test/example/odp_example.c | 1062 | ||||
-rw-r--r-- | test/generator/Makefile.am | 5 | ||||
-rw-r--r-- | test/generator/odp_generator.c | 923 | ||||
-rw-r--r-- | test/l2fwd/Makefile.am | 5 | ||||
-rw-r--r-- | test/l2fwd/odp_l2fwd.c | 637 | ||||
-rw-r--r-- | test/packet/Makefile.am | 5 | ||||
-rw-r--r-- | test/packet/odp_pktio.c | 635 | ||||
-rw-r--r-- | test/packet_netmap/Makefile.am | 7 | ||||
-rw-r--r-- | test/packet_netmap/odp_pktio_netmap.c | 557 | ||||
-rw-r--r-- | test/timer/Makefile.am | 5 | ||||
-rw-r--r-- | test/timer/odp_timer_test.c | 329 |
14 files changed, 3 insertions, 4176 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index bae381e17..9bd7db171 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1 +1 @@ -SUBDIRS = api_test example generator l2fwd packet packet_netmap timer +SUBDIRS = api_test diff --git a/test/README b/test/README new file mode 100644 index 000000000..045f88b2b --- /dev/null +++ b/test/README @@ -0,0 +1,2 @@ +Files in this directory are intended to be terse checks that help ensure +that the ODP API Implementations all perform identically and to specification. diff --git a/test/example/Makefile.am b/test/example/Makefile.am deleted file mode 100644 index aeee0e981..000000000 --- a/test/example/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_example - -dist_odp_example_SOURCES = odp_example.c diff --git a/test/example/odp_example.c b/test/example/odp_example.c deleted file mode 100644 index be9609356..000000000 --- a/test/example/odp_example.c +++ /dev/null @@ -1,1062 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * @example odp_example.c ODP example application - */ - -#include <string.h> -#include <stdlib.h> - -/* ODP main header */ -#include <odp.h> - -/* ODP helper for Linux apps */ -#include <helper/odp_linux.h> - -/* Needs librt*/ -#include <time.h> - -/* GNU lib C */ -#include <getopt.h> - - -#define MAX_WORKERS 32 /**< Max worker threads */ -#define MSG_POOL_SIZE (4*1024*1024) /**< Message pool size */ -#define MAX_ALLOCS 35 /**< Alloc burst size */ -#define QUEUES_PER_PRIO 64 /**< Queue per priority */ -#define QUEUE_ROUNDS (512*1024) /**< Queue test rounds */ -#define ALLOC_ROUNDS (1024*1024) /**< Alloc test rounds */ -#define MULTI_BUFS_MAX 4 /**< Buffer burst size */ -#define TEST_SEC 2 /**< Time test duration in sec */ - -/** Dummy message */ -typedef struct { - int msg_id; /**< Message ID */ - int seq; /**< Sequence number */ -} test_message_t; - -#define MSG_HELLO 1 /**< Hello */ -#define MSG_ACK 2 /**< Ack */ - -/** Test arguments */ -typedef struct { - int core_count; /**< Core count*/ -} test_args_t; - - -/** @private Barrier for test synchronisation */ -static odp_barrier_t test_barrier; - - -/** - * @internal Clear all scheduled queues. Retry to be sure that all - * buffers have been scheduled. - */ -static void clear_sched_queues(void) -{ - odp_buffer_t buf; - - while (1) { - buf = odp_schedule(NULL, ODP_SCHED_NO_WAIT); - - if (buf == ODP_BUFFER_INVALID) - break; - - odp_buffer_free(buf); - } -} - - -static int create_queue(int thr, odp_buffer_pool_t msg_pool, int prio) -{ - char name[] = "sched_XX_00"; - odp_buffer_t buf; - odp_queue_t queue; - - buf = odp_buffer_alloc(msg_pool); - - if (!odp_buffer_is_valid(buf)) { - ODP_ERR(" [%i] msg_pool alloc failed\n", thr); - return -1; - } - - name[6] = '0' + prio/10; - name[7] = '0' + prio - 10*(prio/10); - - queue = odp_queue_lookup(name); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR(" [%i] Queue %s lookup failed.\n", thr, name); - return -1; - } - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - - return 0; -} - -static int create_queues(int thr, odp_buffer_pool_t msg_pool, int prio) -{ - char name[] = "sched_XX_YY"; - odp_buffer_t buf; - odp_queue_t queue; - int i; - - name[6] = '0' + prio/10; - name[7] = '0' + prio - 10*(prio/10); - - /* Alloc and enqueue a buffer per queue */ - for (i = 0; i < QUEUES_PER_PRIO; i++) { - name[9] = '0' + i/10; - name[10] = '0' + i - 10*(i/10); - - queue = odp_queue_lookup(name); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR(" [%i] Queue %s lookup failed.\n", thr, name); - return -1; - } - - buf = odp_buffer_alloc(msg_pool); - - if (!odp_buffer_is_valid(buf)) { - ODP_ERR(" [%i] msg_pool alloc failed\n", thr); - return -1; - } - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - return 0; -} - - -/** - * @internal Test single buffer alloc and free - * - * @param thr Thread - * @param pool Buffer pool - * - * @return 0 if successful - */ -static int test_alloc_single(int thr, odp_buffer_pool_t pool) -{ - int i; - odp_buffer_t temp_buf; - uint64_t t1, t2, cycles, ns; - - t1 = odp_time_get_cycles(); - - for (i = 0; i < ALLOC_ROUNDS; i++) { - temp_buf = odp_buffer_alloc(pool); - - if (!odp_buffer_is_valid(temp_buf)) { - ODP_ERR(" [%i] alloc_single failed\n", thr); - return -1; - } - - odp_buffer_free(temp_buf); - } - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - printf(" [%i] alloc_sng alloc+free %"PRIu64" cycles, %"PRIu64" ns\n", - thr, cycles/ALLOC_ROUNDS, ns/ALLOC_ROUNDS); - - return 0; -} - -/** - * @internal Test multiple buffers alloc and free - * - * @param thr Thread - * @param pool Buffer pool - * - * @return 0 if successful - */ -static int test_alloc_multi(int thr, odp_buffer_pool_t pool) -{ - int i, j; - odp_buffer_t temp_buf[MAX_ALLOCS]; - uint64_t t1, t2, cycles, ns; - - t1 = odp_time_get_cycles(); - - for (i = 0; i < ALLOC_ROUNDS; i++) { - for (j = 0; j < MAX_ALLOCS; j++) { - temp_buf[j] = odp_buffer_alloc(pool); - - if (!odp_buffer_is_valid(temp_buf[j])) { - ODP_ERR(" [%i] alloc_multi failed\n", thr); - return -1; - } - } - - for (; j > 0; j--) - odp_buffer_free(temp_buf[j-1]); - } - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - printf(" [%i] alloc_multi alloc+free %"PRIu64" cycles, %"PRIu64" ns\n", - thr, cycles/(ALLOC_ROUNDS*MAX_ALLOCS), - ns/(ALLOC_ROUNDS*MAX_ALLOCS)); - - return 0; -} - -/** - * @internal Test queue polling - * - * Enqueue to and dequeue to/from a single shared queue. - * - * @param thr Thread - * @param msg_pool Buffer pool - * - * @return 0 if successful - */ -static int test_poll_queue(int thr, odp_buffer_pool_t msg_pool) -{ - odp_buffer_t buf; - test_message_t *t_msg; - odp_queue_t queue; - uint64_t t1, t2, cycles, ns; - int i; - - /* Alloc test message */ - buf = odp_buffer_alloc(msg_pool); - - if (!odp_buffer_is_valid(buf)) { - ODP_ERR(" [%i] msg_pool alloc failed\n", thr); - return -1; - } - - /* odp_buffer_print(buf); */ - - t_msg = odp_buffer_addr(buf); - t_msg->msg_id = MSG_HELLO; - t_msg->seq = 0; - - queue = odp_queue_lookup("poll_queue"); - - if (queue == ODP_QUEUE_INVALID) { - printf(" [%i] Queue lookup failed.\n", thr); - return -1; - } - - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - - buf = odp_queue_deq(queue); - - if (!odp_buffer_is_valid(buf)) { - ODP_ERR(" [%i] Queue empty.\n", thr); - return -1; - } - } - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - printf(" [%i] poll_queue enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, cycles/QUEUE_ROUNDS, ns/QUEUE_ROUNDS); - - odp_buffer_free(buf); - return 0; -} - -/** - * @internal Test scheduling of a single queue - with odp_schedule_one() - * - * Enqueue a buffer to the shared queue. Schedule and enqueue the received - * buffer back into the queue. - * - * @param str Test case name string - * @param thr Thread - * @param msg_pool Buffer pool - * @param prio Priority - * - * @return 0 if successful - */ -static int test_schedule_one_single(const char *str, int thr, - odp_buffer_pool_t msg_pool, int prio) -{ - odp_buffer_t buf; - odp_queue_t queue; - uint64_t t1, t2, cycles, ns; - uint32_t i; - uint32_t tot = 0; - - if (create_queue(thr, msg_pool, prio)) - return -1; - - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - buf = odp_schedule_one(&queue, ODP_SCHED_WAIT); - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - if (odp_queue_sched_type(queue) == ODP_SCHED_SYNC_ATOMIC) - odp_schedule_release_atomic(); - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - tot = i; - - odp_barrier_sync(&test_barrier); - clear_sched_queues(); - - if (tot) { - cycles = cycles/tot; - ns = ns/tot; - } else { - cycles = 0; - ns = 0; - } - - printf(" [%i] %s enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, str, cycles, ns); - - return 0; -} - -/** - * @internal Test scheduling of multiple queues - with odp_schedule_one() - * - * Enqueue a buffer to each queue. Schedule and enqueue the received - * buffer back into the queue it came from. - * - * @param str Test case name string - * @param thr Thread - * @param msg_pool Buffer pool - * @param prio Priority - * - * @return 0 if successful - */ -static int test_schedule_one_many(const char *str, int thr, - odp_buffer_pool_t msg_pool, int prio) -{ - odp_buffer_t buf; - odp_queue_t queue; - uint64_t t1 = 0; - uint64_t t2 = 0; - uint64_t cycles, ns; - uint32_t i; - uint32_t tot = 0; - - if (create_queues(thr, msg_pool, prio)) - return -1; - - /* Start sched-enq loop */ - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - buf = odp_schedule_one(&queue, ODP_SCHED_WAIT); - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - if (odp_queue_sched_type(queue) == ODP_SCHED_SYNC_ATOMIC) - odp_schedule_release_atomic(); - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - tot = i; - - odp_barrier_sync(&test_barrier); - clear_sched_queues(); - - if (tot) { - cycles = cycles/tot; - ns = ns/tot; - } else { - cycles = 0; - ns = 0; - } - - printf(" [%i] %s enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, str, cycles, ns); - - return 0; -} - -/** - * @internal Test scheduling of a single queue - with odp_schedule() - * - * Enqueue a buffer to the shared queue. Schedule and enqueue the received - * buffer back into the queue. - * - * @param str Test case name string - * @param thr Thread - * @param msg_pool Buffer pool - * @param prio Priority - * - * @return 0 if successful - */ -static int test_schedule_single(const char *str, int thr, - odp_buffer_pool_t msg_pool, int prio) -{ - odp_buffer_t buf; - odp_queue_t queue; - uint64_t t1, t2, cycles, ns; - uint32_t i; - uint32_t tot = 0; - - if (create_queue(thr, msg_pool, prio)) - return -1; - - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - buf = odp_schedule(&queue, ODP_SCHED_WAIT); - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - /* Clear possible locally stored buffers */ - odp_schedule_pause(); - - tot = i; - - while (1) { - buf = odp_schedule(&queue, ODP_SCHED_NO_WAIT); - - if (buf == ODP_BUFFER_INVALID) - break; - - tot++; - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - odp_schedule_resume(); - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - odp_barrier_sync(&test_barrier); - clear_sched_queues(); - - if (tot) { - cycles = cycles/tot; - ns = ns/tot; - } else { - cycles = 0; - ns = 0; - } - - printf(" [%i] %s enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, str, cycles, ns); - - return 0; -} - - -/** - * @internal Test scheduling of multiple queues - with odp_schedule() - * - * Enqueue a buffer to each queue. Schedule and enqueue the received - * buffer back into the queue it came from. - * - * @param str Test case name string - * @param thr Thread - * @param msg_pool Buffer pool - * @param prio Priority - * - * @return 0 if successful - */ -static int test_schedule_many(const char *str, int thr, - odp_buffer_pool_t msg_pool, int prio) -{ - odp_buffer_t buf; - odp_queue_t queue; - uint64_t t1 = 0; - uint64_t t2 = 0; - uint64_t cycles, ns; - uint32_t i; - uint32_t tot = 0; - - if (create_queues(thr, msg_pool, prio)) - return -1; - - /* Start sched-enq loop */ - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - buf = odp_schedule(&queue, ODP_SCHED_WAIT); - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - /* Clear possible locally stored buffers */ - odp_schedule_pause(); - - tot = i; - - while (1) { - buf = odp_schedule(&queue, ODP_SCHED_NO_WAIT); - - if (buf == ODP_BUFFER_INVALID) - break; - - tot++; - - if (odp_queue_enq(queue, buf)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - odp_schedule_resume(); - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - odp_barrier_sync(&test_barrier); - clear_sched_queues(); - - if (tot) { - cycles = cycles/tot; - ns = ns/tot; - } else { - cycles = 0; - ns = 0; - } - - printf(" [%i] %s enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, str, cycles, ns); - - return 0; -} - -/** - * @internal Test scheduling of multiple queues with multi_sched and multi_enq - * - * @param str Test case name string - * @param thr Thread - * @param msg_pool Buffer pool - * @param prio Priority - * - * @return 0 if successful - */ -static int test_schedule_multi(const char *str, int thr, - odp_buffer_pool_t msg_pool, int prio) -{ - odp_buffer_t buf[MULTI_BUFS_MAX]; - odp_queue_t queue; - uint64_t t1 = 0; - uint64_t t2 = 0; - uint64_t cycles, ns; - int i, j; - int num; - uint32_t tot = 0; - char name[] = "sched_XX_YY"; - - name[6] = '0' + prio/10; - name[7] = '0' + prio - 10*(prio/10); - - /* Alloc and enqueue a buffer per queue */ - for (i = 0; i < QUEUES_PER_PRIO; i++) { - name[9] = '0' + i/10; - name[10] = '0' + i - 10*(i/10); - - queue = odp_queue_lookup(name); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR(" [%i] Queue %s lookup failed.\n", thr, name); - return -1; - } - - for (j = 0; j < MULTI_BUFS_MAX; j++) { - buf[j] = odp_buffer_alloc(msg_pool); - - if (!odp_buffer_is_valid(buf[j])) { - ODP_ERR(" [%i] msg_pool alloc failed\n", thr); - return -1; - } - } - - if (odp_queue_enq_multi(queue, buf, MULTI_BUFS_MAX)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - /* Start sched-enq loop */ - t1 = odp_time_get_cycles(); - - for (i = 0; i < QUEUE_ROUNDS; i++) { - num = odp_schedule_multi(&queue, ODP_SCHED_WAIT, buf, - MULTI_BUFS_MAX); - - tot += num; - - if (odp_queue_enq_multi(queue, buf, num)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - /* Clear possible locally stored buffers */ - odp_schedule_pause(); - - while (1) { - num = odp_schedule_multi(&queue, ODP_SCHED_NO_WAIT, buf, - MULTI_BUFS_MAX); - - if (num == 0) - break; - - tot += num; - - if (odp_queue_enq_multi(queue, buf, num)) { - ODP_ERR(" [%i] Queue enqueue failed.\n", thr); - return -1; - } - } - - odp_schedule_resume(); - - - t2 = odp_time_get_cycles(); - cycles = odp_time_diff_cycles(t1, t2); - ns = odp_time_cycles_to_ns(cycles); - - odp_barrier_sync(&test_barrier); - clear_sched_queues(); - - if (tot) { - cycles = cycles/tot; - ns = ns/tot; - } else { - cycles = 0; - ns = 0; - } - - printf(" [%i] %s enq+deq %"PRIu64" cycles, %"PRIu64" ns\n", - thr, str, cycles, ns); - - return 0; -} - -/** - * @internal Worker thread - * - * @param arg Arguments - * - * @return NULL on failure - */ -static void *run_thread(void *arg) -{ - int thr; - odp_buffer_pool_t msg_pool; - - thr = odp_thread_id(); - - printf("Thread %i starts on core %i\n", thr, odp_thread_core()); - - /* - * Test barriers back-to-back - */ - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - - /* - * Find the buffer pool - */ - msg_pool = odp_buffer_pool_lookup("msg_pool"); - - if (msg_pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR(" [%i] msg_pool not found\n", thr); - return NULL; - } - - odp_barrier_sync(&test_barrier); - - if (test_alloc_single(thr, msg_pool)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_alloc_multi(thr, msg_pool)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_poll_queue(thr, msg_pool)) - return NULL; - - /* Low prio */ - - odp_barrier_sync(&test_barrier); - - if (test_schedule_one_single("sched_one_s_lo", thr, msg_pool, - ODP_SCHED_PRIO_LOWEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_single("sched_____s_lo", thr, msg_pool, - ODP_SCHED_PRIO_LOWEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_one_many("sched_one_m_lo", thr, msg_pool, - ODP_SCHED_PRIO_LOWEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_many("sched_____m_lo", thr, msg_pool, - ODP_SCHED_PRIO_LOWEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_multi("sched_multi_lo", thr, msg_pool, - ODP_SCHED_PRIO_LOWEST)) - return NULL; - - /* High prio */ - - odp_barrier_sync(&test_barrier); - - if (test_schedule_one_single("sched_one_s_hi", thr, msg_pool, - ODP_SCHED_PRIO_HIGHEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_single("sched_____s_hi", thr, msg_pool, - ODP_SCHED_PRIO_HIGHEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_one_many("sched_one_m_hi", thr, msg_pool, - ODP_SCHED_PRIO_HIGHEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_many("sched_____m_hi", thr, msg_pool, - ODP_SCHED_PRIO_HIGHEST)) - return NULL; - - odp_barrier_sync(&test_barrier); - - if (test_schedule_multi("sched_multi_hi", thr, msg_pool, - ODP_SCHED_PRIO_HIGHEST)) - return NULL; - - - printf("Thread %i exits\n", thr); - fflush(NULL); - return arg; -} - -/** - * @internal Test cycle counter accuracy - */ -static void test_time(void) -{ - struct timespec tp1, tp2; - uint64_t t1, t2; - uint64_t ns1, ns2, cycles; - double err; - - if (clock_gettime(CLOCK_MONOTONIC, &tp2)) { - ODP_ERR("clock_gettime failed.\n"); - return; - } - - printf("\nTime accuracy test (%i sec)\n", TEST_SEC); - - do { - if (clock_gettime(CLOCK_MONOTONIC, &tp1)) { - ODP_ERR("clock_gettime failed.\n"); - return; - } - - } while (tp1.tv_sec == tp2.tv_sec); - - t1 = odp_time_get_cycles(); - - do { - if (clock_gettime(CLOCK_MONOTONIC, &tp2)) { - ODP_ERR("clock_gettime failed.\n"); - return; - } - - } while ((tp2.tv_sec - tp1.tv_sec) < TEST_SEC); - - t2 = odp_time_get_cycles(); - - ns1 = (tp2.tv_sec - tp1.tv_sec)*1000000000; - - if (tp2.tv_nsec > tp1.tv_nsec) - ns1 += tp2.tv_nsec - tp1.tv_nsec; - else - ns1 -= tp1.tv_nsec - tp2.tv_nsec; - - cycles = odp_time_diff_cycles(t1, t2); - ns2 = odp_time_cycles_to_ns(cycles); - - err = ((double)(ns2) - (double)ns1) / (double)ns1; - - printf("clock_gettime %"PRIu64" ns\n", ns1); - printf("odp_time_get_cycles %"PRIu64" cycles\n", cycles); - printf("odp_time_cycles_to_ns %"PRIu64" ns\n", ns2); - printf("odp get cycle error %f%%\n", err*100.0); - - printf("\n"); -} - -/** - * @internal Print help - */ -static void print_usage(void) -{ - printf("\n\nUsage: ./odp_example [options]\n"); - printf("Options:\n"); - printf(" -c, --count <number> core count, core IDs start from 1\n"); - printf(" -h, --help this help\n"); - printf("\n\n"); -} - -/** - * @internal Parse arguments - * - * @param argc Argument count - * @param argv Argument vector - * @param args Test arguments - */ -static void parse_args(int argc, char *argv[], test_args_t *args) -{ - int opt; - int long_index; - - static struct option longopts[] = { - {"count", required_argument, NULL, 'c'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0} - }; - - while (1) { - opt = getopt_long(argc, argv, "+c:h", longopts, &long_index); - - if (opt == -1) - break; /* No more options */ - - switch (opt) { - case 'c': - args->core_count = atoi(optarg); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } -} - - -/** - * Test main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - test_args_t args; - int thr_id; - int num_workers; - odp_buffer_pool_t pool; - void *pool_base; - odp_queue_t queue; - int i, j; - int prios; - int first_core; - - printf("\nODP example starts\n"); - - memset(&args, 0, sizeof(args)); - parse_args(argc, argv, &args); - - memset(thread_tbl, 0, sizeof(thread_tbl)); - - if (odp_init_global()) { - printf("ODP global init failed.\n"); - return -1; - } - - printf("\n"); - printf("ODP system info\n"); - printf("---------------\n"); - printf("ODP API version: %s\n", odp_version_api_str()); - printf("CPU model: %s\n", odp_sys_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_sys_cpu_hz()); - printf("Cache line size: %i\n", odp_sys_cache_line_size()); - printf("Max core count: %i\n", odp_sys_core_count()); - - printf("\n"); - - /* A worker thread per core */ - num_workers = odp_sys_core_count(); - - if (args.core_count) - num_workers = args.core_count; - - /* force to max core count */ - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - printf("num worker threads: %i\n", num_workers); - - /* - * By default core #0 runs Linux kernel background tasks. - * Start mapping thread from core #1 - */ - first_core = 1; - - if (odp_sys_core_count() == 1) - first_core = 0; - - printf("first core: %i\n", first_core); - - /* - * Init this thread. It makes also ODP calls when - * setting up resources for worker threads. - */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* Test cycle count accuracy */ - test_time(); - - /* - * Create message pool - */ - pool_base = odp_shm_reserve("msg_pool", - MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE); - - pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE, - sizeof(test_message_t), - ODP_CACHE_LINE_SIZE, ODP_BUFFER_TYPE_RAW); - - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Pool create failed.\n"); - return -1; - } - - /* odp_buffer_pool_print(pool); */ - - /* - * Create a queue for direct poll test - */ - queue = odp_queue_create("poll_queue", ODP_QUEUE_TYPE_POLL, NULL); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR("Poll queue create failed.\n"); - return -1; - } - - /* - * Create queues for schedule test. QUEUES_PER_PRIO per priority. - */ - prios = odp_schedule_num_prio(); - - for (i = 0; i < prios; i++) { - if (i != ODP_SCHED_PRIO_HIGHEST && - i != ODP_SCHED_PRIO_LOWEST) - continue; - - odp_queue_param_t param; - char name[] = "sched_XX_YY"; - - name[6] = '0' + i/10; - name[7] = '0' + i - 10*(i/10); - - param.sched.prio = i; - param.sched.sync = ODP_SCHED_SYNC_ATOMIC; - param.sched.group = ODP_SCHED_GROUP_DEFAULT; - - for (j = 0; j < QUEUES_PER_PRIO; j++) { - name[9] = '0' + j/10; - name[10] = '0' + j - 10*(j/10); - - queue = odp_queue_create(name, ODP_QUEUE_TYPE_SCHED, - ¶m); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR("Schedule queue create failed.\n"); - return -1; - } - } - } - - odp_shm_print_all(); - - /* Barrier to sync test case execution */ - odp_barrier_init_count(&test_barrier, num_workers); - - /* Create and launch worker threads */ - odp_linux_pthread_create(thread_tbl, num_workers, first_core, - run_thread, NULL); - - /* Wait for worker threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - - printf("ODP example complete\n\n"); - - return 0; -} diff --git a/test/generator/Makefile.am b/test/generator/Makefile.am deleted file mode 100644 index bd6f2005d..000000000 --- a/test/generator/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_generator - -dist_odp_generator_SOURCES = odp_generator.c diff --git a/test/generator/odp_generator.c b/test/generator/odp_generator.c deleted file mode 100644 index e4a72fad8..000000000 --- a/test/generator/odp_generator.c +++ /dev/null @@ -1,923 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * @example odp_generator.c ODP loopback demo application - */ - -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <sys/time.h> - -#include <odp.h> -#include <odp_packet_io.h> -#include <helper/odp_linux.h> -#include <helper/odp_packet_helper.h> -#include <helper/odp_eth.h> -#include <helper/odp_ip.h> -#include <helper/odp_udp.h> -#include <helper/odp_icmp.h> - -#define MAX_WORKERS 32 /**< max number of works */ -#define SHM_PKT_POOL_SIZE (512*2048) /**< pkt pool size */ -#define SHM_PKT_POOL_BUF_SIZE 1856 /**< pkt pool buf size */ - -#define APPL_MODE_UDP 0 /**< UDP mode */ -#define APPL_MODE_PING 1 /**< ping mode */ -#define APPL_MODE_RCV 2 /**< receive mode */ - -/** print appl mode */ -#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x)) - -/** Get rid of path in filename - only for unix-type paths using '/' */ -#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ - strrchr((file_name), '/') + 1 : (file_name)) -/** - * Parsed command line application arguments - */ -typedef struct { - int core_count; /**< system core count */ - int if_count; /**< Number of interfaces to be used */ - char **if_names; /**< Array of pointers to interface names */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ - odp_ethaddr_t srcmac; /**< src mac addr */ - odp_ethaddr_t dstmac; /**< dest mac addr */ - unsigned int srcip; /**< src ip addr */ - unsigned int dstip; /**< dest ip addr */ - int mode; /**< work mode */ - int number; /**< packets number to be sent */ - int payload; /**< data len */ - int timeout; /**< wait time */ - int interval; /**< wait interval ms between sending each packet */ -} appl_args_t; - -/** - * counters -*/ -static struct { - odp_atomic_u64_t seq; /**< ip seq to be send */ - odp_atomic_u64_t ip; /**< ip packets */ - odp_atomic_u64_t udp; /**< udp packets */ - odp_atomic_u64_t icmp; /**< icmp packets */ -} counters; - -/** * Thread specific arguments - */ -typedef struct { - char *pktio_dev; /**< Interface name to use */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ - int mode; /**< Thread mode */ -} thread_args_t; - -/** - * Grouping of both parsed CL args and thread specific args - alloc together - */ -typedef struct { - /** Application (parsed) arguments */ - appl_args_t appl; - /** Thread specific arguments */ - thread_args_t thread[MAX_WORKERS]; -} args_t; - -/** Global pointer to args */ -static args_t *args; - -/* helper funcs */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args); -static void print_info(char *progname, appl_args_t *appl_args); -static void usage(char *progname); -static int scan_ip(char *buf, unsigned int *paddr); -static int scan_mac(char *in, odp_ethaddr_t *des); -static void tv_sub(struct timeval *recvtime, struct timeval *sendtime); - -/** - * Scan ip - * Parse ip address. - * - * @param buf ip address string xxx.xxx.xxx.xx - * @param paddr ip address for odp_packet - * @return 1 success, 0 failed -*/ -static int scan_ip(char *buf, unsigned int *paddr) -{ - int part1, part2, part3, part4; - char tail = 0; - int field; - - if (buf == NULL) - return 0; - - field = sscanf(buf, "%d . %d . %d . %d %c", - &part1, &part2, &part3, &part4, &tail); - - if (field < 4 || field > 5) { - printf("expect 4 field,get %d/n", field); - return 0; - } - - if (tail != 0) { - printf("ip address mixed with non number/n"); - return 0; - } - - if ((part1 >= 0 && part1 <= 255) && (part2 >= 0 && part2 <= 255) && - (part3 >= 0 && part3 <= 255) && (part4 >= 0 && part4 <= 255)) { - if (paddr) - *paddr = part1 << 24 | part2 << 16 | part3 << 8 | part4; - return 1; - } else { - printf("not good ip %d:%d:%d:%d/n", part1, part2, part3, part4); - } - - return 0; -} - -/** - * Scan mac addr form string - * - * @param in mac string - * @param des mac for odp_packet - * @return 1 success, 0 failed - */ -static int scan_mac(char *in, odp_ethaddr_t *des) -{ - int field; - int i; - unsigned int mac[7]; - - field = sscanf(in, "%2x:%2x:%2x:%2x:%2x:%2x", - &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); - - for (i = 0; i < 6; i++) - des->addr[i] = mac[i]; - - if (field != 6) - return 0; - return 1; -} - -/** - * set up an udp packet - * - * @param obuf packet buffer -*/ -static void pack_udp_pkt(odp_buffer_t obuf) -{ - char *buf; - int max; - odp_packet_t pkt; - odp_ethhdr_t *eth; - odp_ipv4hdr_t *ip; - odp_udphdr_t *udp; - unsigned short seq; - - buf = odp_buffer_addr(obuf); - if (buf == NULL) - return; - max = odp_buffer_size(obuf); - if (max <= 0) - return; - - pkt = odp_packet_from_buffer(obuf); - /* ether */ - odp_packet_set_l2_offset(pkt, 0); - eth = (odp_ethhdr_t *)buf; - memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODP_ETHADDR_LEN); - memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODP_ETHADDR_LEN); - eth->type = odp_cpu_to_be_16(ODP_ETHTYPE_IPV4); - /* ip */ - odp_packet_set_l3_offset(pkt, ODP_ETHHDR_LEN); - ip = (odp_ipv4hdr_t *)(buf + ODP_ETHHDR_LEN); - ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); - ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); - ip->ver_ihl = ODP_IPV4 << 4 | ODP_IPV4HDR_IHL_MIN; - ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODP_UDPHDR_LEN + - ODP_IPV4HDR_LEN); - ip->proto = ODP_IPPROTO_UDP; - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; - ip->id = odp_cpu_to_be_16(seq); - ip->chksum = 0; - odp_ipv4_csum_update(pkt); - /* udp */ - odp_packet_set_l4_offset(pkt, ODP_ETHHDR_LEN + ODP_IPV4HDR_LEN); - udp = (odp_udphdr_t *)(buf + ODP_ETHHDR_LEN + ODP_IPV4HDR_LEN); - udp->src_port = 0; - udp->dst_port = 0; - udp->length = odp_cpu_to_be_16(args->appl.payload + ODP_UDPHDR_LEN); - udp->chksum = 0; - udp->chksum = odp_cpu_to_be_16(odp_ipv4_udp_chksum(pkt)); - odp_packet_set_len(pkt, args->appl.payload + ODP_UDPHDR_LEN + - ODP_IPV4HDR_LEN + ODP_ETHHDR_LEN); -} - -/** - * Set up an icmp packet - * - * @param obuf packet buffer -*/ -static void pack_icmp_pkt(odp_buffer_t obuf) -{ - char *buf; - int max; - odp_packet_t pkt; - odp_ethhdr_t *eth; - odp_ipv4hdr_t *ip; - odp_icmphdr_t *icmp; - struct timeval tval; - uint8_t *tval_d; - unsigned short seq; - - buf = odp_buffer_addr(obuf); - if (buf == NULL) - return; - max = odp_buffer_size(obuf); - if (max <= 0) - return; - - args->appl.payload = 56; - pkt = odp_packet_from_buffer(obuf); - /* ether */ - odp_packet_set_l2_offset(pkt, 0); - eth = (odp_ethhdr_t *)buf; - memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODP_ETHADDR_LEN); - memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODP_ETHADDR_LEN); - eth->type = odp_cpu_to_be_16(ODP_ETHTYPE_IPV4); - /* ip */ - odp_packet_set_l3_offset(pkt, ODP_ETHHDR_LEN); - ip = (odp_ipv4hdr_t *)(buf + ODP_ETHHDR_LEN); - ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); - ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); - ip->ver_ihl = ODP_IPV4 << 4 | ODP_IPV4HDR_IHL_MIN; - ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODP_ICMPHDR_LEN + - ODP_IPV4HDR_LEN); - ip->proto = ODP_IPPROTO_ICMP; - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; - ip->id = odp_cpu_to_be_16(seq); - ip->chksum = 0; - odp_ipv4_csum_update(pkt); - /* icmp */ - icmp = (odp_icmphdr_t *)(buf + ODP_ETHHDR_LEN + ODP_IPV4HDR_LEN); - icmp->type = ICMP_ECHO; - icmp->code = 0; - icmp->un.echo.id = 0; - icmp->un.echo.sequence = ip->id; - tval_d = (uint8_t *)(buf + ODP_ETHHDR_LEN + ODP_IPV4HDR_LEN + - ODP_ICMPHDR_LEN); - /* TODO This should be changed to use an - * ODP timer API once one exists. */ - gettimeofday(&tval, NULL); - memcpy(tval_d, &tval, sizeof(struct timeval)); - icmp->chksum = 0; - icmp->chksum = odp_chksum(icmp, args->appl.payload + - ODP_ICMPHDR_LEN); - - odp_packet_set_len(pkt, args->appl.payload + ODP_ICMPHDR_LEN + - ODP_IPV4HDR_LEN + ODP_ETHHDR_LEN); -} - -/** - * Packet IO loopback worker thread using ODP queues - * - * @param arg thread arguments of type 'thread_args_t *' - */ - -static void *gen_send_thread(void *arg) -{ - int thr; - odp_pktio_t pktio; - thread_args_t *thr_args; - odp_queue_t outq_def; - odp_pktio_params_t params; - socket_params_t *sock_params = ¶ms.sock_params; - - odp_buffer_t buf; - - thr = odp_thread_id(); - thr_args = arg; - - /* Open a packet IO instance for this thread */ - sock_params->type = 1; - pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" [%02i] Error: pktio create failed\n", thr); - return NULL; - } - - outq_def = odp_pktio_outq_getdef(pktio); - if (outq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: def output-Q query\n", thr); - return NULL; - } - - printf(" [%02i] created mode: SEND\n", thr); - for (;;) { - int err; - buf = odp_buffer_alloc(thr_args->pool); - if (!odp_buffer_is_valid(buf)) { - ODP_ERR(" [%2i] alloc_single failed\n", thr); - return NULL; - } - - if (args->appl.mode == APPL_MODE_UDP) - pack_udp_pkt(buf); - else if (args->appl.mode == APPL_MODE_PING) - pack_icmp_pkt(buf); - - err = odp_queue_enq(outq_def, buf); - if (err != 0) { - ODP_ERR(" [%02i] send pkt err!\n", thr); - return NULL; - } - - if (args->appl.interval != 0) { - printf(" [%02i] send pkt no:%ju seq %ju\n", - thr, counters.seq, counters.seq%0xffff); - /* TODO use odp timer */ - usleep(args->appl.interval * 1000); - } else { - /* TODO maybe need a rating control */ - /* flood mode use '\r' instead of '\n' */ - printf(" [%02i] send pkt no:%ju seq %ju\r", - thr, counters.seq, counters.seq%0xffff); - } - if (args->appl.number != -1 && counters.seq - >= (unsigned int)args->appl.number) { - break; - } - } - - /* receive number of reply pks until timeout */ - if (args->appl.mode == APPL_MODE_PING && args->appl.number > 0) { - while (args->appl.timeout >= 0) { - if (counters.icmp >= (unsigned int)args->appl.number) - break; - /* TODO use odp timer */ - sleep(1); - args->appl.timeout--; - } - } - - /* print info */ - if (args->appl.mode == APPL_MODE_UDP) { - printf(" [%02i] total send:%ju\n", thr, counters.seq); - } else if (args->appl.mode == APPL_MODE_PING) { - printf(" [%02i] total send:%ju,total receiver %ju\n", - thr, counters.seq, counters.icmp); - } - return arg; -} - -/** - * Print odp packets - * - * @param thr worker id - * @param pkt_tbl packets to be print - * @param len packet number - */ -static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - char *buf; - odp_ipv4hdr_t *ip; - odp_udphdr_t *udp; - odp_icmphdr_t *icmp; - struct timeval tvrecv; - struct timeval tvsend; - double rtt; - unsigned i; - size_t offset; - char msg[1024]; - int rlen; - for (i = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - rlen = 0; - - /* only ip pkts */ - if (!odp_packet_inflag_ipv4(pkt)) - continue; - - odp_atomic_inc_u64(&counters.ip); - rlen += sprintf(msg, "receive Packet proto:IP "); - buf = odp_buffer_addr(odp_buffer_from_packet(pkt)); - ip = (odp_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt)); - rlen += sprintf(msg + rlen, "id %d ", - odp_be_to_cpu_16(ip->id)); - offset = odp_packet_l4_offset(pkt); - - /* udp */ - if (ip->proto == ODP_IPPROTO_UDP) { - odp_atomic_inc_u64(&counters.udp); - udp = (odp_udphdr_t *)(buf + offset); - rlen += sprintf(msg + rlen, "UDP payload %d ", - odp_be_to_cpu_16(udp->length) - - ODP_UDPHDR_LEN); - } - - /* icmp */ - if (ip->proto == ODP_IPPROTO_ICMP) { - icmp = (odp_icmphdr_t *)(buf + offset); - /* echo reply */ - if (icmp->type == ICMP_ECHOREPLY) { - odp_atomic_inc_u64(&counters.icmp); - memcpy(&tvsend, buf + offset + ODP_ICMPHDR_LEN, - sizeof(struct timeval)); - /* TODO This should be changed to use an - * ODP timer API once one exists. */ - gettimeofday(&tvrecv, NULL); - tv_sub(&tvrecv, &tvsend); - rtt = tvrecv.tv_sec*1000 + tvrecv.tv_usec/1000; - rlen += sprintf(msg + rlen, - "ICMP Echo Reply seq %d time %.1f ", - odp_be_to_cpu_16(icmp->un.echo.sequence) - , rtt); - } else if (icmp->type == ICMP_ECHO) { - rlen += sprintf(msg + rlen, - "Icmp Echo Request"); - } - } - - msg[rlen] = '\0'; - printf(" [%02i] %s\n", thr, msg); - } -} - -/** - * Main receive funtion - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *gen_recv_thread(void *arg) -{ - int thr; - odp_pktio_t pktio; - thread_args_t *thr_args; - odp_queue_t inq_def; - odp_pktio_params_t params; - char inq_name[ODP_QUEUE_NAME_LEN]; - odp_queue_param_t qparam; - socket_params_t *sock_params = ¶ms.sock_params; - - odp_packet_t pkt; - odp_buffer_t buf; - - thr = odp_thread_id(); - thr_args = arg; - - /* Open a packet IO instance for this thread */ - sock_params->type = 1; - pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool, ¶ms); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" [%02i] Error: pktio create failed\n", thr); - return NULL; - } - - int ret; - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; - qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; - snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio); - inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; - inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); - if (inq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: pktio queue creation failed\n", thr); - return NULL; - } - - ret = odp_pktio_inq_setdef(pktio, inq_def); - if (ret != 0) { - ODP_ERR(" [%02i] Error: default input-Q setup\n", thr); - return NULL; - } - - printf(" [%02i] created mode: RECEIVE\n", thr); - for (;;) { - /* Use schedule to get buf from any input queue */ - buf = odp_schedule(NULL, ODP_SCHED_WAIT); - - pkt = odp_packet_from_buffer(buf); - /* Drop packets with errors */ - if (odp_unlikely(odp_packet_error(pkt))) { - odp_packet_free(pkt); - continue; - } - - print_pkts(thr, &pkt, 1); - - odp_packet_free(pkt); - } - - return arg; -} -/** - * ODP packet example main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - odp_buffer_pool_t pool; - int thr_id; - int num_workers; - void *pool_base; - int i; - int first_core; - int core_count; - - /* Init ODP before calling anything else */ - if (odp_init_global()) { - ODP_ERR("Error: ODP global init failed.\n"); - exit(EXIT_FAILURE); - } - - /* init counters */ - odp_atomic_init_u64(&counters.seq); - odp_atomic_init_u64(&counters.ip); - odp_atomic_init_u64(&counters.udp); - odp_atomic_init_u64(&counters.icmp); - - /* Reserve memory for args from shared mem */ - args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE); - if (args == NULL) { - ODP_ERR("Error: shared mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - memset(args, 0, sizeof(*args)); - - /* Parse and store the application arguments */ - parse_args(argc, argv, &args->appl); - - /* Print both system and application information */ - print_info(NO_PATH(argv[0]), &args->appl); - - core_count = odp_sys_core_count(); - num_workers = core_count; - - if (args->appl.core_count) - num_workers = args->appl.core_count; - - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - /* ping mode need two worker */ - if (args->appl.mode == APPL_MODE_PING) - num_workers = 2; - - printf("Num worker threads: %i\n", num_workers); - - /* - * By default core #0 runs Linux kernel background tasks. - * Start mapping thread from core #1 - */ - first_core = 1; - - if (core_count == 1) - first_core = 0; - - printf("First core: %i\n\n", first_core); - - /* Init this thread */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* Create packet pool */ - pool_base = odp_shm_reserve("shm_packet_pool", - SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE); - if (pool_base == NULL) { - ODP_ERR("Error: packet pool mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - - pool = odp_buffer_pool_create("packet_pool", pool_base, - SHM_PKT_POOL_SIZE, - SHM_PKT_POOL_BUF_SIZE, - ODP_CACHE_LINE_SIZE, - ODP_BUFFER_TYPE_PACKET); - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Error: packet pool create failed.\n"); - exit(EXIT_FAILURE); - } - odp_buffer_pool_print(pool); - - /* Create and init worker threads */ - memset(thread_tbl, 0, sizeof(thread_tbl)); - - if (args->appl.mode == APPL_MODE_PING) { - args->thread[1].pktio_dev = args->appl.if_names[0]; - args->thread[1].pool = pool; - args->thread[1].mode = args->appl.mode; - odp_linux_pthread_create(thread_tbl, 1, 0, - gen_recv_thread, &args->thread[1]); - - args->thread[0].pktio_dev = args->appl.if_names[0]; - args->thread[0].pool = pool; - args->thread[0].mode = args->appl.mode; - odp_linux_pthread_create(thread_tbl, 1, 0, - gen_send_thread, &args->thread[0]); - - /* only wait send thread to join */ - num_workers = 1; - } else { - for (i = 0; i < num_workers; ++i) { - void *(*thr_run_func) (void *); - int core; - int if_idx; - - core = (first_core + i) % core_count; - - if_idx = i % args->appl.if_count; - - args->thread[i].pktio_dev = args->appl.if_names[if_idx]; - args->thread[i].pool = pool; - args->thread[i].mode = args->appl.mode; - - if (args->appl.mode == APPL_MODE_UDP) { - thr_run_func = gen_send_thread; - } else if (args->appl.mode == APPL_MODE_RCV) { - thr_run_func = gen_recv_thread; - } else { - ODP_ERR("ERR MODE\n"); - exit(EXIT_FAILURE); - } - /* - * Create threads one-by-one instead of all-at-once, - * because each thread might get different arguments. - * Calls odp_thread_create(cpu) for each thread - */ - odp_linux_pthread_create(thread_tbl, 1, - core, thr_run_func, - &args->thread[i]); - } - } - - /* Master thread waits for other threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - printf("Exit\n\n"); - - return 0; -} - - -/** - * Parse and store the command line arguments - * - * @param argc argument count - * @param argv[] argument vector - * @param appl_args Store application arguments here - */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args) -{ - int opt; - int long_index; - char *names, *str, *token, *save; - size_t len; - int i; - static struct option longopts[] = { - {"interface", required_argument, NULL, 'I'}, - {"workers", required_argument, NULL, 'w'}, - {"srcmac", required_argument, NULL, 'a'}, - {"dstmac", required_argument, NULL, 'b'}, - {"srcip", required_argument, NULL, 'c'}, - {"dstip", required_argument, NULL, 'd'}, - {"packetsize", required_argument, NULL, 's'}, - {"mode", required_argument, NULL, 'm'}, - {"count", required_argument, NULL, 'n'}, - {"timeout", required_argument, NULL, 't'}, - {"interval", required_argument, NULL, 'i'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0} - }; - - appl_args->mode = -1; /* Invalid, must be changed by parsing */ - appl_args->number = -1; - appl_args->payload = 56; - appl_args->timeout = -1; - - while (1) { - opt = getopt_long(argc, argv, "+I:a:b:c:d:s:i:m:n:t:w:h", - longopts, &long_index); - if (opt == -1) - break; /* No more options */ - - switch (opt) { - case 'w': - appl_args->core_count = atoi(optarg); - break; - /* parse packet-io interface names */ - case 'I': - len = strlen(optarg); - if (len == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - len += 1; /* add room for '\0' */ - - names = malloc(len); - if (names == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* count the number of tokens separated by ',' */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - } - appl_args->if_count = i; - - if (appl_args->if_count == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* allocate storage for the if names */ - appl_args->if_names = - calloc(appl_args->if_count, sizeof(char *)); - - /* store the if names (reset names string) */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - appl_args->if_names[i] = token; - } - break; - - case 'm': - if (optarg[0] == 'u') { - appl_args->mode = APPL_MODE_UDP; - } else if (optarg[0] == 'p') { - appl_args->mode = APPL_MODE_PING; - } else if (optarg[0] == 'r') { - appl_args->mode = APPL_MODE_RCV; - } else { - ODP_ERR("wrong mode!\n"); - exit(EXIT_FAILURE); - } - break; - - case 'a': - if (scan_mac(optarg, &appl_args->srcmac) != 1) { - ODP_ERR("wrong src mac:%s\n", optarg); - exit(EXIT_FAILURE); - } - break; - - case 'b': - if (scan_mac(optarg, &appl_args->dstmac) != 1) { - ODP_ERR("wrong dst mac:%s\n", optarg); - exit(EXIT_FAILURE); - } - break; - - case 'c': - if (scan_ip(optarg, &appl_args->srcip) != 1) { - ODP_ERR("wrong src ip:%s\n", optarg); - exit(EXIT_FAILURE); - } - break; - - case 'd': - if (scan_ip(optarg, &appl_args->dstip) != 1) { - ODP_ERR("wrong dst ip:%s\n", optarg); - exit(EXIT_FAILURE); - } - break; - - case 's': - appl_args->payload = atoi(optarg); - break; - - case 'n': - appl_args->number = atoi(optarg); - break; - - case 't': - appl_args->timeout = atoi(optarg); - break; - - case 'i': - appl_args->interval = atoi(optarg); - if (appl_args->interval <= 200 && geteuid() != 0) { - ODP_ERR("should be root user\n"); - exit(EXIT_FAILURE); - } - break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } - - if (appl_args->if_count == 0 || appl_args->mode == -1) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - optind = 1; /* reset 'extern optind' from the getopt lib */ -} - -/** - * Print system and application info - */ -static void print_info(char *progname, appl_args_t *appl_args) -{ - int i; - - printf("\n" - "ODP system info\n" - "---------------\n" - "ODP API version: %s\n" - "CPU model: %s\n" - "CPU freq (hz): %"PRIu64"\n" - "Cache line size: %i\n" - "Core count: %i\n" - "\n", - odp_version_api_str(), odp_sys_cpu_model_str(), odp_sys_cpu_hz(), - odp_sys_cache_line_size(), odp_sys_core_count()); - - printf("Running ODP appl: \"%s\"\n" - "-----------------\n" - "IF-count: %i\n" - "Using IFs: ", - progname, appl_args->if_count); - for (i = 0; i < appl_args->if_count; ++i) - printf(" %s", appl_args->if_names[i]); - printf("\n" - "Mode: "); - if (appl_args->mode == 0) - PRINT_APPL_MODE(0); - else - PRINT_APPL_MODE(0); - printf("\n\n"); - fflush(NULL); -} - -/** - * Prinf usage information - */ -static void usage(char *progname) -{ - printf("\n" - "Usage: %s OPTIONS\n" - " E.g. %s -I eth1 -r\n" - "\n" - "OpenDataPlane example application.\n" - "\n" - " Work mode:\n" - " 1.send udp packets\n" - " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 -m u\n" - " 2.receive udp packets\n" - " odp_generator -I eth0 -m r\n" - " 3.work likes ping\n" - " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 -m p\n" - "\n" - "Mandatory OPTIONS:\n" - " -I, --interface Eth interfaces (comma-separated, no spaces)\n" - " -a, --srcmac src mac address\n" - " -b, --dstmac dst mac address\n" - " -c, --srcip src ip address\n" - " -d, --dstip dst ip address\n" - " -s, --packetsize payload length of the packets\n" - " -m, --mode work mode: send udp(u), receive(r), send icmp(p)\n" - " -n, --count the number of packets to be send\n" - " -t, --timeout only for ping mode, wait ICMP reply timeout seconds\n" - " -i, --interval wait interval ms between sending each packet\n" - " default is 1000ms. 0 for flood mode\n" - "\n" - "Optional OPTIONS\n" - " -h, --help Display help and exit.\n" - "\n", NO_PATH(progname), NO_PATH(progname) - ); -} -/** - * calc time period - * - *@param recvtime start time - *@param sendtime end time -*/ -static void tv_sub(struct timeval *recvtime, struct timeval *sendtime) -{ - long sec = recvtime->tv_sec - sendtime->tv_sec; - long usec = recvtime->tv_usec - sendtime->tv_usec; - if (usec >= 0) { - recvtime->tv_sec = sec; - recvtime->tv_usec = usec; - } else { - recvtime->tv_sec = sec - 1; - recvtime->tv_usec = -usec; - } -} diff --git a/test/l2fwd/Makefile.am b/test/l2fwd/Makefile.am deleted file mode 100644 index 2637a2cd0..000000000 --- a/test/l2fwd/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_l2fwd - -dist_odp_l2fwd_SOURCES = odp_l2fwd.c diff --git a/test/l2fwd/odp_l2fwd.c b/test/l2fwd/odp_l2fwd.c deleted file mode 100644 index 035f710b7..000000000 --- a/test/l2fwd/odp_l2fwd.c +++ /dev/null @@ -1,637 +0,0 @@ -/* Copyright (c) 2014, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * @example l2fwd.c ODP basic forwarding application - */ - -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> - -#include <odp.h> -#include <helper/odp_linux.h> -#include <helper/odp_packet_helper.h> -#include <helper/odp_eth.h> -#include <helper/odp_ip.h> - -#define MAX_WORKERS 32 -#define SHM_PKT_POOL_SIZE (512*2048) -#define SHM_PKT_POOL_BUF_SIZE 1856 -#define MAX_PKT_BURST 16 - -#define APPL_MODE_PKT_BURST 0 -#define APPL_MODE_PKT_QUEUE 1 - -#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x)) - -/** Get rid of path in filename - only for unix-type paths using '/' */ -#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ - strrchr((file_name), '/') + 1 : (file_name)) -/** - * Parsed command line application arguments - */ -typedef struct { - int core_count; - int if_count; /**< Number of interfaces to be used */ - char **if_names; /**< Array of pointers to interface names */ - int mode; /**< Packet IO mode */ - int type; /**< Packet IO type */ - int fanout; /**< Packet IO fanout */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ -} appl_args_t; - -/** - * Thread specific arguments - */ -typedef struct { - char *srcif; /**< Source Interface */ - char *dstif; /**< Dest Interface */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ - odp_pktio_t srcpktio; /**< Source pktio handle */ - odp_pktio_t dstpktio; /**< Destination pktio handle */ - int mode; /**< Thread mode */ - int type; /**< Thread i/o type */ - int fanout; /**< Thread i/o fanout */ -} thread_args_t; - -/** - * Grouping of both parsed CL args and thread specific args - alloc together - */ -typedef struct { - /** Application (parsed) arguments */ - appl_args_t appl; - /** Thread specific arguments */ - thread_args_t thread[MAX_WORKERS]; -} args_t; - -/** Global pointer to args */ -static args_t *gbl_args; -static int num_workers; - -/* helper funcs */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); -static void parse_args(int argc, char *argv[], appl_args_t *appl_args); -static void print_info(char *progname, appl_args_t *appl_args); -static void usage(char *progname); - -/** - * Burst mode: pktio for each thread will be created with either same or - * different params - * - * @param arg thread arguments of type 'thread_args_t *' - * @param pool is the packet pool from where buffers should be taken - */ -static odp_pktio_t burst_mode_init_params(void *arg, odp_buffer_pool_t pool) -{ - thread_args_t *args; - odp_pktio_params_t params; - socket_params_t *sock_params = ¶ms.sock_params; - odp_pktio_t pktio; - - args = arg; - /* Open a packet IO instance for this thread */ - sock_params->type = args->type; - sock_params->fanout = args->fanout; - pktio = odp_pktio_open(args->srcif, pool, ¶ms); - if (pktio == ODP_PKTIO_INVALID) - ODP_ERR(" Error: pktio create failed"); - - return pktio; -} - -/** - * Queue mode: pktio for each thread will be created with either same or - * different params. Queues are created and attached to the pktio. - * - * @param arg thread arguments of type 'thread_args_t *' - * @param pool is the packet pool from where buffers should be taken - */ -static odp_pktio_t queue_mode_init_params(void *arg, odp_buffer_pool_t pool) -{ - char inq_name[ODP_QUEUE_NAME_LEN]; - odp_queue_param_t qparam; - odp_queue_t inq_def; - int ret; - odp_pktio_t pktio = ODP_PKTIO_INVALID; - - pktio = burst_mode_init_params(arg, pool); - if (pktio == ODP_PKTIO_INVALID) - return pktio; - /* - * Create and set the default INPUT queue associated with the 'pktio' - * resource - */ - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; - qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; - snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio); - inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; - - inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); - if (inq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" Error: pktio queue creation failed"); - return ODP_PKTIO_INVALID; - } - - ret = odp_pktio_inq_setdef(pktio, inq_def); - if (ret != 0) { - ODP_ERR(" Error: default input-Q setup"); - return ODP_PKTIO_INVALID; - } - - return pktio; -} - -/** - * Packet IO worker thread using ODP queues - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *pktio_queue_thread(void *arg) -{ - int thr, i; - thread_args_t *thr_args; - char dstpktio[MAX_WORKERS+1]; - odp_queue_t outq_def; - odp_packet_t pkt; - odp_buffer_t buf; - unsigned long pkt_cnt = 0; - unsigned long err_cnt = 0; - - thr = odp_thread_id(); - thr_args = arg; - - if (thr_args->srcpktio == 0 || thr_args->dstpktio == 0) { - ODP_ERR("Invalid srcpktio:%d dstpktio:%d\n", - thr_args->srcpktio, thr_args->dstpktio); - return NULL; - } - printf("[%02i] srcif:%s dstif:%s spktio:%02i dpktio:%02i QUEUE mode\n", - thr, thr_args->srcif, thr_args->dstif, thr_args->srcpktio, - thr_args->dstpktio); - - /* Populate an array of destination pktio's in all threads as the - * scheduler can take packets from any input queue - */ - for (i = 0; i < num_workers; i++) - dstpktio[i+1] = gbl_args->thread[i].dstpktio; - - /* Loop packets */ - for (;;) { - odp_pktio_t pktio_tmp; - - /* Use schedule to get buf from any input queue */ - buf = odp_schedule(NULL, ODP_SCHED_WAIT); - - pkt = odp_packet_from_buffer(buf); - /* Drop packets with errors */ - if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) { - ODP_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt); - continue; - } - - pktio_tmp = odp_pktio_get_input(pkt); - outq_def = odp_pktio_outq_getdef(dstpktio[pktio_tmp]); - if (outq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: def output-Q query\n", thr); - return NULL; - } - - /* Enqueue the packet for output */ - odp_queue_enq(outq_def, buf); - - /* Print packet counts every once in a while */ - if (odp_unlikely(pkt_cnt++ % 100000 == 0)) { - printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); - fflush(NULL); - } - } - -/* unreachable */ -} - -/** - * Packet IO worker thread using bursts from/to IO resources - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *pktio_ifburst_thread(void *arg) -{ - int thr; - thread_args_t *thr_args; - int pkts, pkts_ok; - odp_packet_t pkt_tbl[MAX_PKT_BURST]; - unsigned long pkt_cnt = 0; - unsigned long err_cnt = 0; - unsigned long tmp = 0; - - thr = odp_thread_id(); - thr_args = arg; - - if (thr_args->srcpktio == 0 || thr_args->dstpktio == 0) { - ODP_ERR("Invalid srcpktio:%d dstpktio:%d\n", - thr_args->srcpktio, thr_args->dstpktio); - return NULL; - } - printf("[%02i] srcif:%s dstif:%s spktio:%02i dpktio:%02i BURST mode\n", - thr, thr_args->srcif, thr_args->dstif, thr_args->srcpktio, - thr_args->dstpktio); - - /* Loop packets */ - for (;;) { - pkts = odp_pktio_recv(thr_args->srcpktio, pkt_tbl, - MAX_PKT_BURST); - if (pkts > 0) { - /* Drop packets with errors */ - pkts_ok = drop_err_pkts(pkt_tbl, pkts); - if (pkts_ok > 0) - odp_pktio_send(thr_args->dstpktio, pkt_tbl, - pkts_ok); - if (odp_unlikely(pkts_ok != pkts)) - ODP_ERR("Dropped frames:%u - err_cnt:%lu\n", - pkts-pkts_ok, ++err_cnt); - - /* Print packet counts every once in a while */ - tmp += pkts_ok; - if (odp_unlikely((tmp >= 100000) || /* OR first print:*/ - ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) { - pkt_cnt += tmp; - printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); - fflush(NULL); - tmp = 0; - } - } - } - -/* unreachable */ -} - -/** - * ODP L2 forwarding main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - odp_buffer_pool_t pool; - int thr_id; - void *pool_base; - int i; - int first_core; - int core_count; - odp_pktio_t pktio; - - /* Init ODP before calling anything else */ - if (odp_init_global()) { - ODP_ERR("Error: ODP global init failed.\n"); - exit(EXIT_FAILURE); - } - - /* Reserve memory for args from shared mem */ - gbl_args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE); - if (gbl_args == NULL) { - ODP_ERR("Error: shared mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - memset(gbl_args, 0, sizeof(*gbl_args)); - - /* Parse and store the application arguments */ - parse_args(argc, argv, &gbl_args->appl); - - /* Print both system and application information */ - print_info(NO_PATH(argv[0]), &gbl_args->appl); - - core_count = odp_sys_core_count(); - num_workers = core_count; - - if (gbl_args->appl.core_count) - num_workers = gbl_args->appl.core_count; - - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - printf("Num worker threads: %i\n", num_workers); - - if (num_workers < gbl_args->appl.if_count) { - ODP_ERR("Error: core count %d is less than interface count\n", - num_workers); - exit(EXIT_FAILURE); - } - if (gbl_args->appl.if_count % 2 != 0) { - ODP_ERR("Error: interface count %d is odd in fwd appl.\n", - gbl_args->appl.if_count); - exit(EXIT_FAILURE); - } - /* - * By default core #0 runs Linux kernel background tasks. - * Start mapping thread from core #1 - */ - first_core = 1; - - if (core_count == 1) - first_core = 0; - - printf("First core: %i\n\n", first_core); - - /* Init this thread */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* Create packet pool */ - pool_base = odp_shm_reserve("shm_packet_pool", - SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE); - if (pool_base == NULL) { - ODP_ERR("Error: packet pool mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - - pool = odp_buffer_pool_create("packet_pool", pool_base, - SHM_PKT_POOL_SIZE, - SHM_PKT_POOL_BUF_SIZE, - ODP_CACHE_LINE_SIZE, - ODP_BUFFER_TYPE_PACKET); - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Error: packet pool create failed.\n"); - exit(EXIT_FAILURE); - } - odp_buffer_pool_print(pool); - - memset(thread_tbl, 0, sizeof(thread_tbl)); - /* initialize threads params */ - for (i = 0; i < num_workers; ++i) { - int if_idx; - - if_idx = i % gbl_args->appl.if_count; - - gbl_args->thread[i].srcif = gbl_args->appl.if_names[if_idx]; - if (if_idx % 2 == 0) - gbl_args->thread[i].dstif = gbl_args->appl.if_names[if_idx+1]; - else - gbl_args->thread[i].dstif = gbl_args->appl.if_names[if_idx-1]; - gbl_args->thread[i].pool = pool; - gbl_args->thread[i].mode = gbl_args->appl.mode; - gbl_args->thread[i].type = gbl_args->appl.type; - gbl_args->thread[i].fanout = gbl_args->appl.fanout; - - if (gbl_args->appl.mode == APPL_MODE_PKT_BURST) { - pktio = burst_mode_init_params(&gbl_args->thread[i], pool); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" for thread:%02i\n", i); - exit(EXIT_FAILURE); - } - } else { /* APPL_MODE_PKT_QUEUE */ - pktio = queue_mode_init_params(&gbl_args->thread[i], pool); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" for thread:%02i\n", i); - exit(EXIT_FAILURE); - } - } - gbl_args->thread[i].srcpktio = pktio; - } - for (i = 0; i < num_workers; ++i) { - if (i % 2 == 0) - gbl_args->thread[i].dstpktio = gbl_args->thread[i+1].srcpktio; - else - gbl_args->thread[i].dstpktio = gbl_args->thread[i-1].srcpktio; - } - /* Create worker threads */ - for (i = 0; i < num_workers; ++i) { - void *(*thr_run_func) (void *); - int core; - - core = (first_core + i) % core_count; - - if (gbl_args->appl.mode == APPL_MODE_PKT_BURST) - thr_run_func = pktio_ifburst_thread; - else /* APPL_MODE_PKT_QUEUE */ - thr_run_func = pktio_queue_thread; - odp_linux_pthread_create(thread_tbl, 1, core, thr_run_func, - &gbl_args->thread[i]); - } - - /* Master thread waits for other threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - - printf("Exit\n\n"); - - return 0; -} - -/** - * Drop packets which input parsing marked as containing errors. - * - * Frees packets with error and modifies pkt_tbl[] to only contain packets with - * no detected errors. - * - * @param pkt_tbl Array of packet - * @param len Length of pkt_tbl[] - * - * @return Number of packets with no detected error - */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - unsigned pkt_cnt = len; - unsigned i, j; - - for (i = 0, j = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - - if (odp_unlikely(odp_packet_error(pkt))) { - odp_packet_free(pkt); /* Drop */ - pkt_cnt--; - } else if (odp_unlikely(i != j++)) { - pkt_tbl[j-1] = pkt; - } - } - - return pkt_cnt; -} - -/** - * Parse and store the command line arguments - * - * @param argc argument count - * @param argv[] argument vector - * @param appl_args Store application arguments here - */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args) -{ - int opt; - int long_index; - char *names, *str, *token, *save; - size_t len; - int i; - static struct option longopts[] = { - {"count", required_argument, NULL, 'c'}, - {"interface", required_argument, NULL, 'i'}, /* return 'i' */ - {"mode", required_argument, NULL, 'm'}, /* return 'm' */ - {"help", no_argument, NULL, 'h'}, /* return 'h' */ - {NULL, 0, NULL, 0} - }; - - appl_args->mode = -1; /* Invalid, must be changed by parsing */ - appl_args->type = 3; /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */ - appl_args->fanout = 1; /* turn off fanout by default for mmap */ - - while (1) { - opt = getopt_long(argc, argv, "+c:i:m:t:f:h", - longopts, &long_index); - - if (opt == -1) - break; /* No more options */ - - switch (opt) { - case 'c': - appl_args->core_count = atoi(optarg); - break; - /* parse packet-io interface names */ - case 'i': - len = strlen(optarg); - if (len == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - len += 1; /* add room for '\0' */ - - names = malloc(len); - if (names == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* count the number of tokens separated by ',' */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - } - appl_args->if_count = i; - - if (appl_args->if_count == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* allocate storage for the if names */ - appl_args->if_names = - calloc(appl_args->if_count, sizeof(char *)); - - /* store the if names (reset names string) */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - appl_args->if_names[i] = token; - } - break; - - case 'm': - i = atoi(optarg); - if (i == 0) - appl_args->mode = APPL_MODE_PKT_BURST; - else - appl_args->mode = APPL_MODE_PKT_QUEUE; - break; - - case 't': - appl_args->type = atoi(optarg); - break; - - case 'f': - appl_args->fanout = atoi(optarg); - break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } - - if (appl_args->if_count == 0 || appl_args->mode == -1) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - optind = 1; /* reset 'extern optind' from the getopt lib */ -} - -/** - * Print system and application info - */ -static void print_info(char *progname, appl_args_t *appl_args) -{ - int i; - - printf("\n" - "ODP system info\n" - "---------------\n" - "ODP API version: %s\n" - "CPU model: %s\n" - "CPU freq (hz): %"PRIu64"\n" - "Cache line size: %i\n" - "Core count: %i\n" - "\n", - odp_version_api_str(), odp_sys_cpu_model_str(), odp_sys_cpu_hz(), - odp_sys_cache_line_size(), odp_sys_core_count()); - - printf("Running ODP appl: \"%s\"\n" - "-----------------\n" - "IF-count: %i\n" - "Using IFs: ", - progname, appl_args->if_count); - for (i = 0; i < appl_args->if_count; ++i) - printf(" %s", appl_args->if_names[i]); - printf("\n" - "Mode: "); - if (appl_args->mode == APPL_MODE_PKT_BURST) - PRINT_APPL_MODE(APPL_MODE_PKT_BURST); - else - PRINT_APPL_MODE(APPL_MODE_PKT_QUEUE); - printf("\n\n"); - fflush(NULL); -} - -/** - * Prinf usage information - */ -static void usage(char *progname) -{ - printf("\n" - "OpenDataPlane L2 forwarding application.\n" - "\n" - "Usage: %s OPTIONS\n" - " E.g. %s -i eth0,eth1,eth2,eth3 -m 0 -t 1\n" - " In the above example,\n" - " eth0 will send pkts to eth1 and vice versa\n" - " eth2 will send pkts to eth3 and vice versa\n" - "\n" - "Mandatory OPTIONS:\n" - " -i, --interface Eth interfaces (comma-separated, no spaces)\n" - " -m, --mode 0: Burst send&receive packets (no queues)\n" - " 1: Send&receive packets through ODP queues.\n" - " -t, --type 1: ODP_PKTIO_TYPE_SOCKET_BASIC\n" - " 2: ODP_PKTIO_TYPE_SOCKET_MMSG\n" - " 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" - " 4: ODP_PKTIO_TYPE_NETMAP\n" - " Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" - " -f, --fanout 0: off 1: on (Default 1: on)\n" - "\n" - "Optional OPTIONS\n" - " -c, --count <number> Core count.\n" - " -h, --help Display help and exit.\n\n" - "\n", NO_PATH(progname), NO_PATH(progname) - ); -} diff --git a/test/packet/Makefile.am b/test/packet/Makefile.am deleted file mode 100644 index 0a800fce0..000000000 --- a/test/packet/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_pktio - -dist_odp_pktio_SOURCES = odp_pktio.c diff --git a/test/packet/odp_pktio.c b/test/packet/odp_pktio.c deleted file mode 100644 index 91aa6d141..000000000 --- a/test/packet/odp_pktio.c +++ /dev/null @@ -1,635 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * @example odp_example_pktio.c ODP basic packet IO loopback test application - */ - -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> - -#include <odp.h> -#include <helper/odp_linux.h> -#include <helper/odp_packet_helper.h> -#include <helper/odp_eth.h> -#include <helper/odp_ip.h> - -#define MAX_WORKERS 32 -#define SHM_PKT_POOL_SIZE (512*2048) -#define SHM_PKT_POOL_BUF_SIZE 1856 -#define MAX_PKT_BURST 16 - -#define APPL_MODE_PKT_BURST 0 -#define APPL_MODE_PKT_QUEUE 1 - -#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x)) - -/** Get rid of path in filename - only for unix-type paths using '/' */ -#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ - strrchr((file_name), '/') + 1 : (file_name)) -/** - * Parsed command line application arguments - */ -typedef struct { - int core_count; - int if_count; /**< Number of interfaces to be used */ - char **if_names; /**< Array of pointers to interface names */ - int mode; /**< Packet IO mode */ - int type; /**< Packet IO type */ - int fanout; /**< Packet IO fanout */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ -} appl_args_t; - -/** - * Thread specific arguments - */ -typedef struct { - char *pktio_dev; /**< Interface name to use */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ - int mode; /**< Thread mode */ - int type; /**< Thread i/o type */ - int fanout; /**< Thread i/o fanout */ -} thread_args_t; - -/** - * Grouping of both parsed CL args and thread specific args - alloc together - */ -typedef struct { - /** Application (parsed) arguments */ - appl_args_t appl; - /** Thread specific arguments */ - thread_args_t thread[MAX_WORKERS]; -} args_t; - -/** Global pointer to args */ -static args_t *args; - -/* helper funcs */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); -static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len); -static void parse_args(int argc, char *argv[], appl_args_t *appl_args); -static void print_info(char *progname, appl_args_t *appl_args); -static void usage(char *progname); - -/** - * Packet IO loopback worker thread using ODP queues - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *pktio_queue_thread(void *arg) -{ - int thr; - odp_buffer_pool_t pkt_pool; - odp_pktio_t pktio; - thread_args_t *thr_args; - odp_queue_t outq_def; - odp_queue_t inq_def; - char inq_name[ODP_QUEUE_NAME_LEN]; - odp_queue_param_t qparam; - odp_packet_t pkt; - odp_buffer_t buf; - int ret; - unsigned long pkt_cnt = 0; - unsigned long err_cnt = 0; - odp_pktio_params_t params; - socket_params_t *sock_params = ¶ms.sock_params; - - thr = odp_thread_id(); - thr_args = arg; - - printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr, - thr_args->pktio_dev); - - /* Lookup the packet pool */ - pkt_pool = odp_buffer_pool_lookup("packet_pool"); - if (pkt_pool == ODP_BUFFER_POOL_INVALID || pkt_pool != thr_args->pool) { - ODP_ERR(" [%02i] Error: pkt_pool not found\n", thr); - return NULL; - } - - /* Open a packet IO instance for this thread */ - sock_params->type = thr_args->type; - sock_params->fanout = thr_args->fanout; - pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, ¶ms); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" [%02i] Error: pktio create failed\n", thr); - return NULL; - } - - /* - * Create and set the default INPUT queue associated with the 'pktio' - * resource - */ - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; - qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; - snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)pktio); - inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; - - inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); - if (inq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: pktio queue creation failed\n", thr); - return NULL; - } - - ret = odp_pktio_inq_setdef(pktio, inq_def); - if (ret != 0) { - ODP_ERR(" [%02i] Error: default input-Q setup\n", thr); - return NULL; - } - - printf(" [%02i] created pktio:%02i, queue mode (ATOMIC queues)\n" - " default pktio%02i-INPUT queue:%u\n", - thr, pktio, pktio, inq_def); - - /* Loop packets */ - for (;;) { - odp_pktio_t pktio_tmp; - -#if 1 - /* Use schedule to get buf from any input queue */ - buf = odp_schedule(NULL, ODP_SCHED_WAIT); -#else - /* Always dequeue from the same input queue */ - buf = odp_queue_deq(inq_def); - if (!odp_buffer_is_valid(buf)) - continue; -#endif - - pkt = odp_packet_from_buffer(buf); - - /* Drop packets with errors */ - if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) { - ODP_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt); - continue; - } - - pktio_tmp = odp_pktio_get_input(pkt); - outq_def = odp_pktio_outq_getdef(pktio_tmp); - - if (outq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: def output-Q query\n", thr); - return NULL; - } - - /* Swap Eth MACs and possibly IP-addrs before sending back */ - swap_pkt_addrs(&pkt, 1); - - /* Enqueue the packet for output */ - odp_queue_enq(outq_def, buf); - - /* Print packet counts every once in a while */ - if (odp_unlikely(pkt_cnt++ % 100000 == 0)) { - printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); - fflush(NULL); - } - } - -/* unreachable */ -} - -/** - * Packet IO loopback worker thread using bursts from/to IO resources - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *pktio_ifburst_thread(void *arg) -{ - int thr; - odp_buffer_pool_t pkt_pool; - odp_pktio_t pktio; - thread_args_t *thr_args; - int pkts, pkts_ok; - odp_packet_t pkt_tbl[MAX_PKT_BURST]; - unsigned long pkt_cnt = 0; - unsigned long err_cnt = 0; - unsigned long tmp = 0; - odp_pktio_params_t params; - socket_params_t *sock_params = ¶ms.sock_params; - - thr = odp_thread_id(); - thr_args = arg; - - printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr, - thr_args->pktio_dev); - - /* Lookup the packet pool */ - pkt_pool = odp_buffer_pool_lookup("packet_pool"); - if (pkt_pool == ODP_BUFFER_POOL_INVALID || pkt_pool != thr_args->pool) { - ODP_ERR(" [%02i] Error: pkt_pool not found\n", thr); - return NULL; - } - - /* Open a packet IO instance for this thread */ - sock_params->type = thr_args->type; - sock_params->fanout = thr_args->fanout; - pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, ¶ms); - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" [%02i] Error: pktio create failed.\n", thr); - return NULL; - } - - printf(" [%02i] created pktio:%02i, burst mode\n", - thr, pktio); - - /* Loop packets */ - for (;;) { - pkts = odp_pktio_recv(pktio, pkt_tbl, MAX_PKT_BURST); - if (pkts > 0) { - /* Drop packets with errors */ - pkts_ok = drop_err_pkts(pkt_tbl, pkts); - if (pkts_ok > 0) { - /* Swap Eth MACs and IP-addrs */ - swap_pkt_addrs(pkt_tbl, pkts_ok); - odp_pktio_send(pktio, pkt_tbl, pkts_ok); - } - - if (odp_unlikely(pkts_ok != pkts)) - ODP_ERR("Dropped frames:%u - err_cnt:%lu\n", - pkts-pkts_ok, ++err_cnt); - - /* Print packet counts every once in a while */ - tmp += pkts_ok; - if (odp_unlikely((tmp >= 100000) || /* OR first print:*/ - ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) { - pkt_cnt += tmp; - printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); - fflush(NULL); - tmp = 0; - } - } - } - -/* unreachable */ -} - -/** - * ODP packet example main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - odp_buffer_pool_t pool; - int thr_id; - int num_workers; - void *pool_base; - int i; - int first_core; - int core_count; - - /* Init ODP before calling anything else */ - if (odp_init_global()) { - ODP_ERR("Error: ODP global init failed.\n"); - exit(EXIT_FAILURE); - } - - /* Reserve memory for args from shared mem */ - args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE); - if (args == NULL) { - ODP_ERR("Error: shared mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - memset(args, 0, sizeof(*args)); - - /* Parse and store the application arguments */ - parse_args(argc, argv, &args->appl); - - /* Print both system and application information */ - print_info(NO_PATH(argv[0]), &args->appl); - - core_count = odp_sys_core_count(); - num_workers = core_count; - - if (args->appl.core_count) - num_workers = args->appl.core_count; - - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - printf("Num worker threads: %i\n", num_workers); - - /* - * By default core #0 runs Linux kernel background tasks. - * Start mapping thread from core #1 - */ - first_core = 1; - - if (core_count == 1) - first_core = 0; - - printf("First core: %i\n\n", first_core); - - /* Init this thread */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* Create packet pool */ - pool_base = odp_shm_reserve("shm_packet_pool", - SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE); - if (pool_base == NULL) { - ODP_ERR("Error: packet pool mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - - pool = odp_buffer_pool_create("packet_pool", pool_base, - SHM_PKT_POOL_SIZE, - SHM_PKT_POOL_BUF_SIZE, - ODP_CACHE_LINE_SIZE, - ODP_BUFFER_TYPE_PACKET); - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Error: packet pool create failed.\n"); - exit(EXIT_FAILURE); - } - odp_buffer_pool_print(pool); - - /* Create and init worker threads */ - memset(thread_tbl, 0, sizeof(thread_tbl)); - for (i = 0; i < num_workers; ++i) { - void *(*thr_run_func) (void *); - int core; - int if_idx; - - core = (first_core + i) % core_count; - - if_idx = i % args->appl.if_count; - - args->thread[i].pktio_dev = args->appl.if_names[if_idx]; - args->thread[i].pool = pool; - args->thread[i].mode = args->appl.mode; - args->thread[i].type = args->appl.type; - args->thread[i].fanout = args->appl.fanout; - - if (args->appl.mode == APPL_MODE_PKT_BURST) - thr_run_func = pktio_ifburst_thread; - else /* APPL_MODE_PKT_QUEUE */ - thr_run_func = pktio_queue_thread; - /* - * Create threads one-by-one instead of all-at-once, - * because each thread might get different arguments. - * Calls odp_thread_create(cpu) for each thread - */ - odp_linux_pthread_create(thread_tbl, 1, core, thr_run_func, - &args->thread[i]); - } - - /* Master thread waits for other threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - - printf("Exit\n\n"); - - return 0; -} - -/** - * Drop packets which input parsing marked as containing errors. - * - * Frees packets with error and modifies pkt_tbl[] to only contain packets with - * no detected errors. - * - * @param pkt_tbl Array of packet - * @param len Length of pkt_tbl[] - * - * @return Number of packets with no detected error - */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - unsigned pkt_cnt = len; - unsigned i, j; - - for (i = 0, j = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - - if (odp_unlikely(odp_packet_error(pkt))) { - odp_packet_free(pkt); /* Drop */ - pkt_cnt--; - } else if (odp_unlikely(i != j++)) { - pkt_tbl[j-1] = pkt; - } - } - - return pkt_cnt; -} - -/** - * Swap eth src<->dst and IP src<->dst addresses - * - * @param pkt_tbl Array of packets - * @param len Length of pkt_tbl[] - */ - -static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - odp_ethhdr_t *eth; - odp_ethaddr_t tmp_addr; - odp_ipv4hdr_t *ip; - uint32be_t ip_tmp_addr; /* tmp ip addr */ - unsigned i; - - for (i = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - if (odp_packet_inflag_eth(pkt)) { - eth = (odp_ethhdr_t *)odp_packet_l2(pkt); - - tmp_addr = eth->dst; - eth->dst = eth->src; - eth->src = tmp_addr; - - if (odp_packet_inflag_ipv4(pkt)) { - /* IPv4 */ - ip = (odp_ipv4hdr_t *)odp_packet_l3(pkt); - - ip_tmp_addr = ip->src_addr; - ip->src_addr = ip->dst_addr; - ip->dst_addr = ip_tmp_addr; - } - } - } -} - -/** - * Parse and store the command line arguments - * - * @param argc argument count - * @param argv[] argument vector - * @param appl_args Store application arguments here - */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args) -{ - int opt; - int long_index; - char *names, *str, *token, *save; - size_t len; - int i; - static struct option longopts[] = { - {"count", required_argument, NULL, 'c'}, - {"interface", required_argument, NULL, 'i'}, /* return 'i' */ - {"mode", required_argument, NULL, 'm'}, /* return 'm' */ - {"help", no_argument, NULL, 'h'}, /* return 'h' */ - {NULL, 0, NULL, 0} - }; - - appl_args->mode = -1; /* Invalid, must be changed by parsing */ - appl_args->type = 3; /* 3: ODP_PKTIO_TYPE_SOCKET_MMAP */ - appl_args->fanout = 1; /* turn off fanout by default for mmap */ - - while (1) { - opt = getopt_long(argc, argv, "+c:i:m:t:f:h", - longopts, &long_index); - - if (opt == -1) - break; /* No more options */ - - switch (opt) { - case 'c': - appl_args->core_count = atoi(optarg); - break; - /* parse packet-io interface names */ - case 'i': - len = strlen(optarg); - if (len == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - len += 1; /* add room for '\0' */ - - names = malloc(len); - if (names == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* count the number of tokens separated by ',' */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - } - appl_args->if_count = i; - - if (appl_args->if_count == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* allocate storage for the if names */ - appl_args->if_names = - calloc(appl_args->if_count, sizeof(char *)); - - /* store the if names (reset names string) */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - appl_args->if_names[i] = token; - } - break; - - case 'm': - i = atoi(optarg); - if (i == 0) - appl_args->mode = APPL_MODE_PKT_BURST; - else - appl_args->mode = APPL_MODE_PKT_QUEUE; - break; - - case 't': - appl_args->type = atoi(optarg); - break; - - case 'f': - appl_args->fanout = atoi(optarg); - break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } - - if (appl_args->if_count == 0 || appl_args->mode == -1) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - optind = 1; /* reset 'extern optind' from the getopt lib */ -} - -/** - * Print system and application info - */ -static void print_info(char *progname, appl_args_t *appl_args) -{ - int i; - - printf("\n" - "ODP system info\n" - "---------------\n" - "ODP API version: %s\n" - "CPU model: %s\n" - "CPU freq (hz): %"PRIu64"\n" - "Cache line size: %i\n" - "Core count: %i\n" - "\n", - odp_version_api_str(), odp_sys_cpu_model_str(), odp_sys_cpu_hz(), - odp_sys_cache_line_size(), odp_sys_core_count()); - - printf("Running ODP appl: \"%s\"\n" - "-----------------\n" - "IF-count: %i\n" - "Using IFs: ", - progname, appl_args->if_count); - for (i = 0; i < appl_args->if_count; ++i) - printf(" %s", appl_args->if_names[i]); - printf("\n" - "Mode: "); - if (appl_args->mode == APPL_MODE_PKT_BURST) - PRINT_APPL_MODE(APPL_MODE_PKT_BURST); - else - PRINT_APPL_MODE(APPL_MODE_PKT_QUEUE); - printf("\n\n"); - fflush(NULL); -} - -/** - * Prinf usage information - */ -static void usage(char *progname) -{ - printf("\n" - "Usage: %s OPTIONS\n" - " E.g. %s -i eth1,eth2,eth3 -m 0\n" - "\n" - "OpenDataPlane example application.\n" - "\n" - "Mandatory OPTIONS:\n" - " -i, --interface Eth interfaces (comma-separated, no spaces)\n" - " -m, --mode 0: Burst send&receive packets (no queues)\n" - " 1: Send&receive packets through ODP queues.\n" - " -t, --type 1: ODP_PKTIO_TYPE_SOCKET_BASIC\n" - " 2: ODP_PKTIO_TYPE_SOCKET_MMSG\n" - " 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" - " 4: ODP_PKTIO_TYPE_NETMAP\n" - " Default: 3: ODP_PKTIO_TYPE_SOCKET_MMAP\n" - " -f, --fanout 0: off 1: on (Default 1: on)\n" - "\n" - "Optional OPTIONS\n" - " -c, --count <number> Core count.\n" - " -h, --help Display help and exit.\n" - "\n", NO_PATH(progname), NO_PATH(progname) - ); -} diff --git a/test/packet_netmap/Makefile.am b/test/packet_netmap/Makefile.am deleted file mode 100644 index 50e7f85ac..000000000 --- a/test/packet_netmap/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -if ODP_NETMAP_ENABLED -bin_PROGRAMS = odp_pktio_netmap -endif - -dist_odp_pktio_netmap_SOURCES = odp_pktio_netmap.c diff --git a/test/packet_netmap/odp_pktio_netmap.c b/test/packet_netmap/odp_pktio_netmap.c deleted file mode 100644 index 7d33b19b5..000000000 --- a/test/packet_netmap/odp_pktio_netmap.c +++ /dev/null @@ -1,557 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP basic packet IO loopback test application - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <getopt.h> -#include <unistd.h> - -#include <linux/if_ether.h> -#include <linux/ip.h> -#include <arpa/inet.h> - -#include <odp.h> -#include <helper/odp_linux.h> -#include <helper/odp_packet_helper.h> -#include <helper/odp_eth.h> -#include <helper/odp_ip.h> -#include <helper/odp_packet_helper.h> - -#include <odp_pktio_netmap.h> - -#define MAX_WORKERS 32 -#define MAX_IFS 16 -#define SHM_PKT_POOL_SIZE (512*2048) -#define SHM_PKT_POOL_BUF_SIZE 1856 -#define MAX_PKT_BURST 16 - -#define PKTIO_MODE_SOCK 0 -#define PKTIO_MODE_NETMAP 1 - -/** Get rid of path in filename - only for unix-type paths using '/' */ -#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ - strrchr((file_name), '/') + 1 : (file_name)) - -/** - * Interface parameters obatained from app arguments - */ -typedef struct { - char if_name[32]; - int pktio_mode; /**< Socket mode or netmap mode */ -} if_info_t; - -/** - * Parsed command line application arguments - */ -typedef struct { - int if_count; /**< Number of interfaces to be used */ - if_info_t *ifs; /**< Array of interface config options */ - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ -} appl_args_t; - -/** - * Thread specific arguments - * In this netmap example, there is a thread polling a network interface - * and another thread polling the ring that is used by the software stack - * to send packets to the same network interface. Each of the two threads - * needs to know which is the output queue corresponding to the other thread - * to be able to pass packets between the stack and the nic. This queue is - * defined by bridge_q below. - */ -typedef struct { - odp_pktio_t pktio; - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ - char *pktio_dev; /**< Interface name to use */ - int netmap_mode; /**< Either poll the hardware rings or the - rings associated with the host stack */ - odp_queue_t bridge_q; /**< Connect the network stack with the NIC */ -} pktio_info_t; - -/** - * Grouping of both parsed CL args and thread specific args - alloc together - */ -typedef struct { - /** Application (parsed) arguments */ - appl_args_t appl; - /** pktio entries: one for SW ring and one for HW ring */ - pktio_info_t pktios[2 * MAX_IFS]; - /** TODO: find a way to associate private data with pktios */ - /** Lookup table: find pktio_info_t based on pktio id */ - pktio_info_t *pktio_lt[ODP_CONFIG_PKTIO_ENTRIES]; -} args_t; - -/** Global pointer to args */ -static args_t *args; - -/* helper funcs */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len); -static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len); -static void parse_args(int argc, char *argv[], appl_args_t *appl_args); -static void print_info(char *progname, appl_args_t *appl_args); -static void usage(char *progname); - -/** - * Packet IO loopback worker thread using ODP queues - * - * @param arg thread arguments of type 'thread_args_t *' - */ -static void *pktio_queue_thread(void *arg) -{ - int thr; - odp_buffer_pool_t pkt_pool; - odp_packet_t pkt; - odp_buffer_t buf; - unsigned long pkt_cnt = 0; - unsigned long err_cnt = 0; - - (void)arg; - - thr = odp_thread_id(); - printf("Pktio thread [%02i] starts\n", thr); - - /* Lookup the packet pool */ - pkt_pool = odp_buffer_pool_lookup("packet_pool"); - if (pkt_pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR(" [%02i] Error: pkt_pool not found\n", thr); - return NULL; - } - - /* Loop packets */ - for (;;) { - odp_pktio_t pktio_tmp; - odp_queue_t outq_def; - pktio_info_t *pktio_info; - - /* Use schedule to get buf from any input queue */ - buf = odp_schedule(NULL, ODP_SCHED_WAIT); - - pkt = odp_packet_from_buffer(buf); - - /* Drop packets with errors */ - if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) { - ODP_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt); - continue; - } - - pktio_tmp = odp_pktio_get_input(pkt); - if (pktio_tmp == ODP_PKTIO_INVALID) { - ODP_ERR("[%02i] Error: invalid pktio\n", thr); - return NULL; - } - - outq_def = odp_pktio_outq_getdef(pktio_tmp); - - if (outq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Error: def output-Q query\n", - thr); - return NULL; - } - - /* Lookup the thread associated with the entry */ - pktio_info = args->pktio_lt[pktio_tmp]; - - /* Send back packets arrived on physical interface */ - if (pktio_info->netmap_mode == ODP_NETMAP_MODE_HW) { - odp_packet_t pkt_copy; - - pkt_copy = odp_packet_alloc(pkt_pool); - - if (odp_packet_copy(pkt_copy, pkt) != 0) { - ODP_ERR("Packet copy failed!\n"); - odp_packet_free(pkt_copy); - } else { - swap_pkt_addrs(&pkt_copy, 1); - odp_queue_enq(outq_def, - odp_buffer_from_packet(pkt_copy)); - } - } - - odp_queue_enq(pktio_info->bridge_q, buf); - - /* Print packet counts every once in a while */ - if (odp_unlikely(pkt_cnt++ % 100000 == 0)) { - printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); - fflush(NULL); - } - } - -/* unreachable */ -} - -/** - * ODP packet example main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - odp_buffer_pool_t pool; - int thr_id; - int num_workers; - void *pool_base; - int i; - - /* Init ODP before calling anything else */ - if (odp_init_global()) { - ODP_ERR("Error: ODP global init failed.\n"); - exit(EXIT_FAILURE); - } - - /* Reserve memory for args from shared mem */ - args = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE); - if (args == NULL) { - ODP_ERR("Error: shared mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - memset(args, 0, sizeof(*args)); - - /* Parse and store the application arguments */ - parse_args(argc, argv, &args->appl); - - /* Print both system and application information */ - print_info(NO_PATH(argv[0]), &args->appl); - - num_workers = odp_sys_core_count(); - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - /* Init this thread */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* Create packet pool */ - pool_base = odp_shm_reserve("shm_packet_pool", - SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE); - if (pool_base == NULL) { - ODP_ERR("Error: packet pool mem alloc failed.\n"); - exit(EXIT_FAILURE); - } - - pool = odp_buffer_pool_create("packet_pool", pool_base, - SHM_PKT_POOL_SIZE, - SHM_PKT_POOL_BUF_SIZE, - ODP_CACHE_LINE_SIZE, - ODP_BUFFER_TYPE_PACKET); - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Error: packet pool create failed.\n"); - exit(EXIT_FAILURE); - } - odp_buffer_pool_print(pool); - - for (i = 0; i < 2 * args->appl.if_count; ++i) { - odp_pktio_params_t params; - netmap_params_t *nm_params = ¶ms.nm_params; - char inq_name[ODP_QUEUE_NAME_LEN]; - odp_queue_t inq_def; - odp_queue_param_t qparam; - odp_pktio_t pktio; - int ret; - - /* Create a pktio polling the hardware rings and one that polls - * the software ring associated with the physical interface - */ - - args->pktios[i].pktio_dev = args->appl.ifs[i / 2].if_name; - memset(nm_params, 0, sizeof(*nm_params)); - nm_params->type = ODP_PKTIO_TYPE_NETMAP; - if (i % 2) { - nm_params->netmap_mode = ODP_NETMAP_MODE_SW; - nm_params->ringid = 0; - } else { - nm_params->netmap_mode = ODP_NETMAP_MODE_HW; - nm_params->ringid = 0; - } - pktio = odp_pktio_open(args->pktios[i].pktio_dev, - pool, ¶ms); - /* Open a packet IO instance for this thread */ - if (pktio == ODP_PKTIO_INVALID) { - ODP_ERR(" [%02i] Err: pktio create\n", i); - return -1; - } - - args->pktios[i].pktio = pktio; - args->pktios[i].pool = pool; - args->pktios[i].netmap_mode = nm_params->netmap_mode; - /* Save pktio_info in the lookup table */ - args->pktio_lt[pktio] = &args->pktios[i]; - /* - * Create and set the default INPUT queue associated with the - * 'pktio' resource - */ - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; - qparam.sched.sync = ODP_SCHED_SYNC_NONE; - qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; - snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", - (int)pktio); - inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; - - inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, - &qparam); - if (inq_def == ODP_QUEUE_INVALID) { - ODP_ERR(" [%02i] Err: pktio q create\n", i); - return -1; - } - - ret = odp_pktio_inq_setdef(pktio, inq_def); - if (ret != 0) { - ODP_ERR(" [%02i] Err: default input-Q setup\n" - , i); - return -1; - } - - printf(" [%02i] created pktio:%02i, queue mode\n" - " default pktio%02i-INPUT queue:%u\n", - i, pktio, pktio, inq_def); - - /* Prepare for bridging: set bridge_q queue ids */ - if (i % 2) { - odp_pktio_t pktio_bridge; - odp_queue_t outq_def; - - pktio_bridge = args->pktios[i-1].pktio; - outq_def = odp_pktio_outq_getdef(pktio_bridge); - args->pktios[i].bridge_q = outq_def; - - pktio_bridge = args->pktios[i].pktio; - outq_def = odp_pktio_outq_getdef(pktio_bridge); - args->pktios[i-1].bridge_q = outq_def; - } - } - - memset(thread_tbl, 0, sizeof(thread_tbl)); - for (i = 0; i < num_workers; ++i) { - - /* - * Create threads one-by-one instead of all-at-once, - * because each thread might get different arguments - */ - odp_linux_pthread_create(thread_tbl, 1, i, pktio_queue_thread, - NULL); - } - - /* Master thread waits for other threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - - printf("Exit\n\n"); - - return 0; -} - -/** - * Drop packets which input parsing marked as containing errors. - * - * Frees packets with error and modifies pkt_tbl[] to only contain packets with - * no detected errors. - * - * @param pkt_tbl Array of packet - * @param len Length of pkt_tbl[] - * - * @return Number of packets with no detected error - */ -static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - unsigned pkt_cnt = len; - unsigned i, j; - - for (i = 0, j = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - - if (odp_unlikely(odp_packet_error(pkt))) { - odp_packet_free(pkt); /* Drop */ - pkt_cnt--; - } else if (odp_unlikely(i != j++)) { - pkt_tbl[j-1] = pkt; - } - } - - return pkt_cnt; -} - -/** - * Swap eth src<->dst and IP src<->dst addresses - * - * @param pkt_tbl Array of packets - * @param len Length of pkt_tbl[] - */ -static void swap_pkt_addrs(odp_packet_t pkt_tbl[], unsigned len) -{ - odp_packet_t pkt; - odp_ethhdr_t *eth; - odp_ethaddr_t tmp_addr; - odp_ipv4hdr_t *ip; - uint32be_t ip_tmp_addr; /* tmp ip addr */ - unsigned i; - - for (i = 0; i < len; ++i) { - pkt = pkt_tbl[i]; - if (odp_packet_inflag_eth(pkt)) { - eth = (odp_ethhdr_t *)odp_packet_l2(pkt); - - tmp_addr = eth->dst; - eth->dst = eth->src; - eth->src = tmp_addr; - - if (odp_packet_inflag_ipv4(pkt)) { - /* IPv4 */ - ip = (odp_ipv4hdr_t *)odp_packet_l3(pkt); - - ip_tmp_addr = ip->src_addr; - ip->src_addr = ip->dst_addr; - ip->dst_addr = ip_tmp_addr; - } - } - } -} - -/** - * Parse and store the command line arguments - * - * @param argc argument count - * @param argv[] argument vector - * @param appl_args Store application arguments here - */ -static void parse_args(int argc, char *argv[], appl_args_t *appl_args) -{ - int opt; - int long_index; - char *names, *str, *token, *save; - size_t len; - int i; - static struct option longopts[] = { - {"interface", required_argument, NULL, 'i'}, /* return 'i' */ - {"help", no_argument, NULL, 'h'}, /* return 'h' */ - {NULL, 0, NULL, 0} - }; - - while (1) { - opt = getopt_long(argc, argv, "+i:h", longopts, &long_index); - - if (opt == -1) - break; /* No more options */ - - switch (opt) { - /* parse packet-io interface names */ - case 'i': - len = strlen(optarg); - if (len == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - len += 1; /* add room for '\0' */ - - names = malloc(len); - if (names == NULL) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* count the number of tokens separated by ',' */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - } - appl_args->if_count = i; - - if (appl_args->if_count == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - /* allocate storage for the if names */ - appl_args->ifs = - calloc(appl_args->if_count, sizeof(if_info_t)); - - /* store the if names (reset names string) */ - strcpy(names, optarg); - for (str = names, i = 0;; str = NULL, i++) { - token = strtok_r(str, ",", &save); - if (token == NULL) - break; - strncpy(appl_args->ifs[i].if_name, token, - sizeof(appl_args->ifs[i].if_name)); - appl_args->ifs[i].pktio_mode = - PKTIO_MODE_NETMAP; - } - break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } - - if (appl_args->if_count == 0) { - usage(argv[0]); - exit(EXIT_FAILURE); - } - - optind = 1; /* reset 'extern optind' from the getopt lib */ -} - -/** - * Print system and application info - */ -static void print_info(char *progname, appl_args_t *appl_args) -{ - int i; - - printf("\n" - "ODP system info\n" - "---------------\n" - "ODP API version: %s\n" - "CPU model: %s\n" - "CPU freq (hz): %"PRIu64"\n" - "Cache line size: %i\n" - "Core count: %i\n" - "\n", - odp_version_api_str(), odp_sys_cpu_model_str(), odp_sys_cpu_hz(), - odp_sys_cache_line_size(), odp_sys_core_count() - ); - printf("Running ODP appl: \"%s\"\n" - "-----------------\n" - "IF-count: %i\n" - "Using IFs: ", - progname, appl_args->if_count); - for (i = 0; i < appl_args->if_count; ++i) - printf(" %s", appl_args->ifs[i].if_name); - printf("\n" - "Mode: "); - printf("\n\n"); - fflush(NULL); -} - -/** - * Prinf usage information - */ -static void usage(char *progname) -{ - printf("\n" - "Usage: %s OPTIONS\n" - " E.g. %s -i eth1,eth2,eth3\n" - "\n" - "OpenDataPlane example application.\n" - "\n" - "Mandatory OPTIONS:\n" - " -i, --interface Eth interfaces (comma-separated, no spaces)\n" - "\n" - "Optional OPTIONS\n" - " -h, --help Display help and exit.\n" - "\n", NO_PATH(progname), NO_PATH(progname) - ); -} diff --git a/test/timer/Makefile.am b/test/timer/Makefile.am deleted file mode 100644 index 096ff49de..000000000 --- a/test/timer/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -include $(top_srcdir)/test/Makefile.inc - -bin_PROGRAMS = odp_timer_test - -dist_odp_timer_test_SOURCES = odp_timer_test.c diff --git a/test/timer/odp_timer_test.c b/test/timer/odp_timer_test.c deleted file mode 100644 index dbe0e5bed..000000000 --- a/test/timer/odp_timer_test.c +++ /dev/null @@ -1,329 +0,0 @@ -/* Copyright (c) 2013, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * @example odp_timer_test.c ODP timer example application - */ - -#include <string.h> -#include <stdlib.h> - -/* ODP main header */ -#include <odp.h> - -/* ODP helper for Linux apps */ -#include <helper/odp_linux.h> - -/* GNU lib C */ -#include <getopt.h> - - -#define MAX_WORKERS 32 /**< Max worker threads */ -#define MSG_POOL_SIZE (4*1024*1024) /**< Message pool size */ - -/** Test arguments */ -typedef struct { - int core_count; /**< Core count*/ -} test_args_t; - - -/** @private Barrier for test synchronisation */ -static odp_barrier_t test_barrier; - -/** @private Timer handle*/ -static odp_timer_t test_timer; - - -/** @private test timeout */ -static void test_timeouts(int thr) -{ - uint64_t tick; - odp_queue_t queue; - odp_buffer_t buf; - int num = 10; - - ODP_DBG(" [%i] test_timeouts\n", thr); - - queue = odp_queue_lookup("timer_queue"); - - tick = odp_timer_current_tick(test_timer); - - tick += 100; - - odp_timer_absolute_tmo(test_timer, tick, - queue, ODP_BUFFER_INVALID); - - ODP_DBG(" [%i] current tick %"PRIu64"\n", thr, tick); - - while (1) { - odp_timeout_t tmo; - - buf = odp_schedule_one(&queue, ODP_SCHED_WAIT); - - tmo = odp_timeout_from_buffer(buf); - tick = odp_timeout_tick(tmo); - - ODP_DBG(" [%i] timeout, tick %"PRIu64"\n", thr, tick); - - odp_buffer_free(buf); - - num--; - - if (num == 0) - break; - - tick += 100; - - odp_timer_absolute_tmo(test_timer, tick, - queue, ODP_BUFFER_INVALID); - } - - if (odp_queue_sched_type(queue) == ODP_SCHED_SYNC_ATOMIC) - odp_schedule_release_atomic(); -} - - -/** - * @internal Worker thread - * - * @param arg Arguments - * - * @return NULL on failure - */ -static void *run_thread(void *arg) -{ - int thr; - odp_buffer_pool_t msg_pool; - - thr = odp_thread_id(); - - printf("Thread %i starts on core %i\n", thr, odp_thread_core()); - - /* - * Test barriers back-to-back - */ - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - odp_barrier_sync(&test_barrier); - - /* - * Find the buffer pool - */ - msg_pool = odp_buffer_pool_lookup("msg_pool"); - - if (msg_pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR(" [%i] msg_pool not found\n", thr); - return NULL; - } - - odp_barrier_sync(&test_barrier); - - test_timeouts(thr); - - - printf("Thread %i exits\n", thr); - fflush(NULL); - return arg; -} - - -/** - * @internal Print help - */ -static void print_usage(void) -{ - printf("\n\nUsage: ./odp_example [options]\n"); - printf("Options:\n"); - printf(" -c, --count <number> core count, core IDs start from 1\n"); - printf(" -h, --help this help\n"); - printf("\n\n"); -} - - -/** - * @internal Parse arguments - * - * @param argc Argument count - * @param argv Argument vector - * @param args Test arguments - */ -static void parse_args(int argc, char *argv[], test_args_t *args) -{ - int opt; - int long_index; - - static struct option longopts[] = { - {"count", required_argument, NULL, 'c'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0} - }; - - while (1) { - opt = getopt_long(argc, argv, "+c:h", longopts, &long_index); - - if (opt == -1) - break; /* No more options */ - - switch (opt) { - case 'c': - args->core_count = atoi(optarg); - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - default: - break; - } - } -} - - -/** - * Test main function - */ -int main(int argc, char *argv[]) -{ - odp_linux_pthread_t thread_tbl[MAX_WORKERS]; - test_args_t args; - int thr_id; - int num_workers; - odp_buffer_pool_t pool; - void *pool_base; - odp_queue_t queue; - int first_core; - uint64_t cycles, ns; - odp_queue_param_t param; - - printf("\nODP example starts\n"); - - memset(&args, 0, sizeof(args)); - parse_args(argc, argv, &args); - - memset(thread_tbl, 0, sizeof(thread_tbl)); - - if (odp_init_global()) { - printf("ODP global init failed.\n"); - return -1; - } - - printf("\n"); - printf("ODP system info\n"); - printf("---------------\n"); - printf("ODP API version: %s\n", odp_version_api_str()); - printf("CPU model: %s\n", odp_sys_cpu_model_str()); - printf("CPU freq (hz): %"PRIu64"\n", odp_sys_cpu_hz()); - printf("Cache line size: %i\n", odp_sys_cache_line_size()); - printf("Max core count: %i\n", odp_sys_core_count()); - - printf("\n"); - - /* A worker thread per core */ - num_workers = odp_sys_core_count(); - - if (args.core_count) - num_workers = args.core_count; - - /* force to max core count */ - if (num_workers > MAX_WORKERS) - num_workers = MAX_WORKERS; - - printf("num worker threads: %i\n", num_workers); - - /* - * By default core #0 runs Linux kernel background tasks. - * Start mapping thread from core #1 - */ - first_core = 1; - - if (odp_sys_core_count() == 1) - first_core = 0; - - printf("first core: %i\n", first_core); - - /* - * Init this thread. It makes also ODP calls when - * setting up resources for worker threads. - */ - thr_id = odp_thread_create(0); - odp_init_local(thr_id); - - /* - * Create message pool - */ - pool_base = odp_shm_reserve("msg_pool", - MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE); - - pool = odp_buffer_pool_create("msg_pool", pool_base, MSG_POOL_SIZE, - 0, - ODP_CACHE_LINE_SIZE, - ODP_BUFFER_TYPE_TIMEOUT); - - if (pool == ODP_BUFFER_POOL_INVALID) { - ODP_ERR("Pool create failed.\n"); - return -1; - } - - /* - * Create a queue for timer test - */ - memset(¶m, 0, sizeof(param)); - param.sched.prio = ODP_SCHED_PRIO_DEFAULT; - param.sched.sync = ODP_SCHED_SYNC_NONE; - param.sched.group = ODP_SCHED_GROUP_DEFAULT; - - queue = odp_queue_create("timer_queue", ODP_QUEUE_TYPE_SCHED, ¶m); - - if (queue == ODP_QUEUE_INVALID) { - ODP_ERR("Timer queue create failed.\n"); - return -1; - } - - test_timer = odp_timer_create("test_timer", pool, - 1000000, 1000000, 1000000000000UL); - - - odp_shm_print_all(); - - printf("CPU freq %"PRIu64" hz\n", odp_sys_cpu_hz()); - printf("Cycles vs nanoseconds:\n"); - ns = 0; - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - - for (ns = 1; ns <= 100000000000UL; ns *= 10) { - cycles = odp_time_ns_to_cycles(ns); - - printf(" %12"PRIu64" ns -> %12"PRIu64" cycles\n", ns, - cycles); - printf(" %12"PRIu64" cycles -> %12"PRIu64" ns\n", cycles, - odp_time_cycles_to_ns(cycles)); - } - - printf("\n"); - - /* Barrier to sync test case execution */ - odp_barrier_init_count(&test_barrier, num_workers); - - /* Create and launch worker threads */ - odp_linux_pthread_create(thread_tbl, num_workers, first_core, - run_thread, NULL); - - /* Wait for worker threads to exit */ - odp_linux_pthread_join(thread_tbl, num_workers); - - printf("ODP timer test complete\n\n"); - - return 0; -} |