diff options
Diffstat (limited to 'example')
-rw-r--r-- | example/Makefile.am | 4 | ||||
-rw-r--r-- | example/cli/.gitignore | 3 | ||||
-rw-r--r-- | example/cli/Makefile.am | 31 | ||||
-rw-r--r-- | example/cli/odp_cli.c | 176 | ||||
-rwxr-xr-x | example/cli/odp_cli_run.sh | 9 | ||||
-rw-r--r-- | example/debug/odp_debug.c | 331 | ||||
-rw-r--r-- | example/m4/configure.m4 | 1 | ||||
-rw-r--r-- | example/timer/odp_timer_accuracy.c | 66 |
8 files changed, 545 insertions, 76 deletions
diff --git a/example/Makefile.am b/example/Makefile.am index fc4623d1f..d6d242cf9 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -18,3 +18,7 @@ SUBDIRS = classifier \ if HAVE_DW_ATOMIC_CMP_EXC SUBDIRS += ipfragreass endif + +if helper_cli +SUBDIRS += cli +endif diff --git a/example/cli/.gitignore b/example/cli/.gitignore new file mode 100644 index 000000000..2a19d7a64 --- /dev/null +++ b/example/cli/.gitignore @@ -0,0 +1,3 @@ +odp_cli +*.log +*.trs diff --git a/example/cli/Makefile.am b/example/cli/Makefile.am new file mode 100644 index 000000000..0e97a09ed --- /dev/null +++ b/example/cli/Makefile.am @@ -0,0 +1,31 @@ +include $(top_srcdir)/example/Makefile.inc + +bin_PROGRAMS = odp_cli + +odp_cli_SOURCES = odp_cli.c + +if test_example +TESTS = odp_cli_run.sh +endif + +EXTRA_DIST = odp_cli_run.sh + +# If building out-of-tree, make check will not copy the scripts and data to the +# $(builddir) assuming that all commands are run locally. However this prevents +# running tests on a remote target using LOG_COMPILER. +# So copy all script and data files explicitly here. +all-local: + if [ "x$(srcdir)" != "x$(builddir)" ]; then \ + for f in $(EXTRA_DIST); do \ + if [ -e $(srcdir)/$$f ]; then \ + mkdir -p $(builddir)/$$(dirname $$f); \ + cp -f $(srcdir)/$$f $(builddir)/$$f; \ + fi \ + done \ + fi +clean-local: + if [ "x$(srcdir)" != "x$(builddir)" ]; then \ + for f in $(EXTRA_DIST); do \ + rm -f $(builddir)/$$f; \ + done \ + fi diff --git a/example/cli/odp_cli.c b/example/cli/odp_cli.c new file mode 100644 index 000000000..e3998129c --- /dev/null +++ b/example/cli/odp_cli.c @@ -0,0 +1,176 @@ +/* Copyright (c) 2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * ODP CLI Helper Example + * + * This example shows how to start and stop ODP CLI using the CLI helper + * API functions. This example application can also be used to try out + * the CLI by connecting to a running application with a telnet client. + */ + +#include <odp_api.h> +#include <odp/helper/odph_api.h> + +#include <stdio.h> +#include <stdint.h> +#include <signal.h> + +typedef struct { + int time; + char *addr; + uint16_t port; +} options_t; + +static void usage(const char *prog) +{ + printf("\n" + "Usage: %s [options]\n" + "\n" + "OPTIONS:\n" + " -t, --time <sec> Keep CLI open for <sec> seconds. (default -1 (infinite))\n" + " -a, --address <addr> Bind listening socket to IP address <addr>.\n" + " -p, --port <port> Bind listening socket to port <port>.\n" + "\n" + "ODP helper defaults are used for address and port, if the options are\n" + "not given.\n" + "\n", + prog); +} + +static void parse_args(int argc, char *argv[], options_t *opt) +{ + static const struct option longopts[] = { + { "time", required_argument, NULL, 't' }, + { "address", required_argument, NULL, 'a' }, + { "port", required_argument, NULL, 'p' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } + }; + + static const char *shortopts = "+t:a:p:h"; + + while (1) { + int c = getopt_long(argc, argv, shortopts, longopts, NULL); + + if (c == -1) + break; /* No more options */ + + switch (c) { + case 't': + opt->time = atoi(optarg); + break; + case 'a': + opt->addr = optarg; + break; + case 'p': + opt->port = atoi(optarg); + break; + default: + usage(argv[0]); + exit(EXIT_SUCCESS); + break; + } + } + + optind = 1; /* reset 'extern optind' from the getopt lib */ +} + +static volatile int shutdown_sig; + +static void sig_handler(int signo) +{ + (void)signo; + + shutdown_sig = 1; +} + +int main(int argc, char *argv[]) +{ + signal(SIGINT, sig_handler); + + odph_helper_options_t helper_options; + + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } + + odp_init_t init; + + odp_init_param_init(&init); + init.mem_model = helper_options.mem_model; + + options_t opt = { + .time = -1, + .addr = NULL, + .port = 0, + }; + + parse_args(argc, argv, &opt); + + /* Initialize ODP. */ + + odp_instance_t inst; + + if (odp_init_global(&inst, &init, NULL)) { + ODPH_ERR("Global init failed.\n"); + exit(EXIT_FAILURE); + } + + if (odp_init_local(inst, ODP_THREAD_CONTROL)) { + ODPH_ERR("Local init failed.\n"); + exit(EXIT_FAILURE); + } + + /* Prepare CLI parameters. */ + + odph_cli_param_t cli_param; + + odph_cli_param_init(&cli_param); + + if (opt.addr) + cli_param.address = opt.addr; + + if (opt.port) + cli_param.port = opt.port; + + /* Start CLI server. */ + if (odph_cli_start(inst, &cli_param)) { + ODPH_ERR("CLI start failed.\n"); + exit(EXIT_FAILURE); + } + + printf("CLI server started on %s:%d\n", cli_param.address, cli_param.port); + + /* Wait for the given number of seconds. */ + for (int i = 0; (opt.time < 0 || i < opt.time) && !shutdown_sig; i++) + odp_time_wait_ns(ODP_TIME_SEC_IN_NS); + + printf("Stopping CLI server.\n"); + + /* Stop CLI server. */ + if (odph_cli_stop()) { + ODPH_ERR("CLI stop failed.\n"); + exit(EXIT_FAILURE); + } + + /* Terminate ODP. */ + + if (odp_term_local()) { + ODPH_ERR("Local term failed.\n"); + exit(EXIT_FAILURE); + } + + if (odp_term_global(inst)) { + ODPH_ERR("Global term failed.\n"); + exit(EXIT_FAILURE); + } + + return 0; +} diff --git a/example/cli/odp_cli_run.sh b/example/cli/odp_cli_run.sh new file mode 100755 index 000000000..0dc00b793 --- /dev/null +++ b/example/cli/odp_cli_run.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# +# Copyright (c) 2021, Nokia +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +./odp_cli${EXEEXT} -t 2 diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c index ef9597906..48591134a 100644 --- a/example/debug/odp_debug.c +++ b/example/debug/odp_debug.c @@ -1,20 +1,27 @@ -/* Copyright (c) 2020, Nokia +/* Copyright (c) 2020-2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <stdlib.h> #include <stdio.h> +#include <stdint.h> +#include <inttypes.h> #include <string.h> #include <getopt.h> #include <odp_api.h> +#include <odp/helper/odph_api.h> typedef struct test_global_t { + int system; int shm; - int shm_all; int pool; int queue; + int pktio; + int ipsec; + int timer; } test_global_t; @@ -27,10 +34,13 @@ static void print_usage(void) "are called when no options are given.\n" "\n" "OPTIONS:\n" - " -S, --shm_all Call odp_shm_print_all()\n" + " -S, --system Call odp_sys_info_print() and odp_sys_config_print()\n" " -s, --shm Create a SHM and call odp_shm_print()\n" " -p, --pool Create various types of pools and call odp_pool_print()\n" " -q, --queue Create various types of queues and call odp_queue_print()\n" + " -i, --interface Create packet IO interface (loop) and call odp_pktio_print()\n" + " -I, --ipsec Call odp_ipsec_print()\n" + " -t, --timer Call timer pool, timer and timeout print functions\n" " -h, --help Display help and exit.\n\n"); } @@ -39,14 +49,17 @@ static int parse_options(int argc, char *argv[], test_global_t *global) int opt, long_index; const struct option longopts[] = { - {"shm_all", no_argument, NULL, 'S'}, + {"system", no_argument, NULL, 'S'}, {"shm", no_argument, NULL, 's'}, {"pool", no_argument, NULL, 'p'}, {"queue", no_argument, NULL, 'q'}, + {"interface", no_argument, NULL, 'i'}, + {"ipsec", no_argument, NULL, 'I'}, + {"timer", no_argument, NULL, 't'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; - const char *shortopts = "+Sspqh"; + const char *shortopts = "+SspqiIth"; int ret = 0; while (1) { @@ -57,7 +70,7 @@ static int parse_options(int argc, char *argv[], test_global_t *global) switch (opt) { case 'S': - global->shm_all = 1; + global->system = 1; break; case 's': global->shm = 1; @@ -68,6 +81,15 @@ static int parse_options(int argc, char *argv[], test_global_t *global) case 'q': global->queue = 1; break; + case 'i': + global->pktio = 1; + break; + case 'I': + global->ipsec = 1; + break; + case 't': + global->timer = 1; + break; case 'h': default: print_usage(); @@ -78,32 +100,26 @@ static int parse_options(int argc, char *argv[], test_global_t *global) return ret; } -static int shm_debug(test_global_t *global) +static int shm_debug(void) { const char *name = "debug_shm"; odp_shm_t shm = ODP_SHM_INVALID; - if (global->shm) { - shm = odp_shm_reserve(name, 8 * 1024, 64, 0); - if (shm == ODP_SHM_INVALID) { - printf("SHM reserve failed: %s\n", name); - return -1; - } + shm = odp_shm_reserve(name, 8 * 1024, 64, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("SHM reserve failed: %s\n", name); + return -1; } - if (global->shm_all) { - printf("\n"); - odp_shm_print_all(); - } + printf("\n"); + odp_shm_print_all(); - if (global->shm) { - printf("\n"); - odp_shm_print(shm); + printf("\n"); + odp_shm_print(shm); - if (odp_shm_free(shm)) { - printf("SHM free failed: %s\n", name); - return -1; - } + if (odp_shm_free(shm)) { + ODPH_ERR("SHM free failed: %s\n", name); + return -1; } return 0; @@ -114,7 +130,7 @@ static int buffer_debug(odp_pool_t pool) odp_buffer_t buf = odp_buffer_alloc(pool); if (buf == ODP_BUFFER_INVALID) { - printf("Buffer alloc failed\n"); + ODPH_ERR("Buffer alloc failed\n"); return -1; } @@ -131,13 +147,16 @@ static int packet_debug(odp_pool_t pool, int len) odp_packet_t pkt = odp_packet_alloc(pool, len); if (pkt == ODP_PACKET_INVALID) { - printf("Packet alloc failed\n"); + ODPH_ERR("Packet alloc failed\n"); return -1; } printf("\n"); odp_packet_print(pkt); + printf("\n"); + odp_packet_print_data(pkt, 0, len); + odp_packet_free(pkt); return 0; @@ -159,7 +178,7 @@ static int pool_debug(void) pool = odp_pool_create(name, ¶m); if (pool == ODP_POOL_INVALID) { - printf("Pool create failed: %s\n", name); + ODPH_ERR("Pool create failed: %s\n", name); return -1; } @@ -170,7 +189,7 @@ static int pool_debug(void) return -1; if (odp_pool_destroy(pool)) { - printf("Pool destroy failed: %s\n", name); + ODPH_ERR("Pool destroy failed: %s\n", name); return -1; } @@ -184,7 +203,7 @@ static int pool_debug(void) pool = odp_pool_create(name, ¶m); if (pool == ODP_POOL_INVALID) { - printf("Pool create failed: %s\n", name); + ODPH_ERR("Pool create failed: %s\n", name); return -1; } @@ -195,7 +214,7 @@ static int pool_debug(void) return -1; if (odp_pool_destroy(pool)) { - printf("Pool destroy failed: %s\n", name); + ODPH_ERR("Pool destroy failed: %s\n", name); return -1; } @@ -207,7 +226,7 @@ static int pool_debug(void) pool = odp_pool_create(name, ¶m); if (pool == ODP_POOL_INVALID) { - printf("Pool create failed: %s\n", name); + ODPH_ERR("Pool create failed: %s\n", name); return -1; } @@ -215,7 +234,7 @@ static int pool_debug(void) odp_pool_print(pool); if (odp_pool_destroy(pool)) { - printf("Pool destroy failed: %s\n", name); + ODPH_ERR("Pool destroy failed: %s\n", name); return -1; } @@ -235,21 +254,18 @@ static int queue_debug(void) queue = odp_queue_create(name, ¶m); if (queue == ODP_QUEUE_INVALID) { - printf("Queue create failed: %s\n", name); + ODPH_ERR("Queue create failed: %s\n", name); return -1; } printf("\n"); + odp_queue_print_all(); + + printf("\n"); odp_queue_print(queue); if (odp_queue_destroy(queue)) { - printf("Queue destroy failed: %s\n", name); - return -1; - } - - /* Configure scheduler before creating any scheduled queues */ - if (odp_schedule_config(NULL)) { - printf("Schedule config failed\n"); + ODPH_ERR("Queue destroy failed: %s\n", name); return -1; } @@ -260,7 +276,7 @@ static int queue_debug(void) queue = odp_queue_create(name, ¶m); if (queue == ODP_QUEUE_INVALID) { - printf("Queue create failed: %s\n", name); + ODPH_ERR("Queue create failed: %s\n", name); return -1; } @@ -268,7 +284,172 @@ static int queue_debug(void) odp_queue_print(queue); if (odp_queue_destroy(queue)) { - printf("Queue destroy failed: %s\n", name); + ODPH_ERR("Queue destroy failed: %s\n", name); + return -1; + } + + return 0; +} + +static int pktio_debug(void) +{ + odp_pool_t pool; + odp_pool_param_t pool_param; + odp_pktio_t pktio; + int pkt_len = 100; + + odp_pool_param_init(&pool_param); + pool_param.type = ODP_POOL_PACKET; + pool_param.pkt.num = 10; + pool_param.pkt.len = pkt_len; + + pool = odp_pool_create("debug_pktio_pool", &pool_param); + + if (pool == ODP_POOL_INVALID) { + ODPH_ERR("Pool create failed\n"); + return -1; + } + + pktio = odp_pktio_open("loop", pool, NULL); + + if (pktio == ODP_PKTIO_INVALID) { + ODPH_ERR("Pktio open failed\n"); + return -1; + } + + printf("\n"); + odp_pktio_print(pktio); + + if (odp_pktio_close(pktio)) { + ODPH_ERR("Pktio close failed\n"); + return -1; + } + + if (odp_pool_destroy(pool)) { + ODPH_ERR("Pool destroy failed\n"); + return -1; + } + + return 0; +} + +static int ipsec_debug(void) +{ + printf("\n"); + odp_ipsec_print(); + + return 0; +} + +static int timer_debug(void) +{ + odp_pool_t pool; + odp_pool_param_t pool_param; + odp_timeout_t timeout; + odp_timer_capability_t timer_capa; + odp_timer_pool_t timer_pool; + odp_timer_pool_param_t timer_param; + odp_timer_t timer; + odp_queue_t queue; + odp_queue_param_t queue_param; + odp_event_t event; + uint64_t tick; + uint64_t max_tmo = ODP_TIME_SEC_IN_NS; + uint64_t res = 100 * ODP_TIME_MSEC_IN_NS; + + odp_pool_param_init(&pool_param); + pool_param.type = ODP_POOL_TIMEOUT; + pool_param.tmo.num = 10; + + pool = odp_pool_create("debug_timer", &pool_param); + + if (pool == ODP_POOL_INVALID) { + ODPH_ERR("Pool create failed\n"); + return -1; + } + + timeout = odp_timeout_alloc(pool); + if (timeout == ODP_TIMEOUT_INVALID) { + ODPH_ERR("Timeout alloc failed\n"); + return -1; + } + + if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) { + ODPH_ERR("Timer capa failed\n"); + return -1; + } + + if (timer_capa.max_tmo.max_tmo < max_tmo) + max_tmo = timer_capa.max_tmo.max_tmo; + + if (timer_capa.max_tmo.res_ns > res) + res = timer_capa.max_tmo.res_ns; + + memset(&timer_param, 0, sizeof(timer_param)); + timer_param.res_ns = res; + timer_param.min_tmo = max_tmo / 10; + timer_param.max_tmo = max_tmo; + timer_param.num_timers = 10; + timer_param.clk_src = ODP_CLOCK_CPU; + + timer_pool = odp_timer_pool_create("debug_timer", &timer_param); + + if (timer_pool == ODP_TIMER_POOL_INVALID) { + ODPH_ERR("Timer pool create failed\n"); + return -1; + } + + odp_timer_pool_start(); + + odp_queue_param_init(&queue_param); + if (timer_capa.queue_type_sched) + queue_param.type = ODP_QUEUE_TYPE_SCHED; + + queue = odp_queue_create("debug_timer", &queue_param); + if (queue == ODP_QUEUE_INVALID) { + ODPH_ERR("Queue create failed.\n"); + return -1; + } + + printf("\n"); + odp_timer_pool_print(timer_pool); + + tick = odp_timer_ns_to_tick(timer_pool, max_tmo / 2); + + timer = odp_timer_alloc(timer_pool, queue, (void *)(uintptr_t)0xdeadbeef); + + printf("\n"); + odp_timeout_print(timeout); + + event = odp_timeout_to_event(timeout); + if (odp_timer_set_rel(timer, tick, &event) != ODP_TIMER_SUCCESS) + ODPH_ERR("Timer set failed.\n"); + + printf("\n"); + odp_timer_print(timer); + + event = odp_timer_free(timer); + + if (event == ODP_EVENT_INVALID) { + ODPH_ERR("Timer free failed.\n"); + } else { + timeout = odp_timeout_from_event(event); + + printf("\n"); + odp_timeout_print(timeout); + + odp_timeout_free(timeout); + } + + odp_timer_pool_destroy(timer_pool); + + if (odp_queue_destroy(queue)) { + ODPH_ERR("Queue destroy failed\n"); + return -1; + } + + if (odp_pool_destroy(pool)) { + ODPH_ERR("Pool destroy failed\n"); return -1; } @@ -285,50 +466,80 @@ int main(int argc, char *argv[]) if (argc < 2) { /* If not arguments, run all test cases */ - global->shm_all = 1; + global->system = 1; global->shm = 1; global->pool = 1; global->queue = 1; + global->pktio = 1; + global->ipsec = 1; + global->timer = 1; } else { if (parse_options(argc, argv, global)) - return -1; + exit(EXIT_FAILURE); } if (odp_init_global(&inst, NULL, NULL)) { - printf("Global init failed.\n"); - return -1; + ODPH_ERR("Global init failed.\n"); + exit(EXIT_FAILURE); } if (odp_init_local(inst, ODP_THREAD_CONTROL)) { - printf("Local init failed.\n"); - return -1; + ODPH_ERR("Local init failed.\n"); + exit(EXIT_FAILURE); } - odp_sys_info_print(); + /* Configure scheduler before creating any scheduled queues */ + if (odp_schedule_config(NULL)) { + ODPH_ERR("Schedule config failed\n"); + exit(EXIT_FAILURE); + } - if ((global->shm_all || global->shm) && shm_debug(global)) { - printf("SHM debug failed.\n"); - return -1; + if (global->system) { + printf("\n"); + odp_sys_info_print(); + + printf("\n"); + odp_sys_config_print(); + } + + if (global->shm && shm_debug()) { + ODPH_ERR("SHM debug failed.\n"); + exit(EXIT_FAILURE); } if (global->pool && pool_debug()) { - printf("Pool debug failed.\n"); - return -1; + ODPH_ERR("Pool debug failed.\n"); + exit(EXIT_FAILURE); } if (global->queue && queue_debug()) { - printf("Queue debug failed.\n"); - return -1; + ODPH_ERR("Queue debug failed.\n"); + exit(EXIT_FAILURE); + } + + if (global->pktio && pktio_debug()) { + ODPH_ERR("Packet debug failed.\n"); + exit(EXIT_FAILURE); + } + + if (global->ipsec && ipsec_debug()) { + ODPH_ERR("IPSEC debug failed.\n"); + exit(EXIT_FAILURE); + } + + if (global->timer && timer_debug()) { + ODPH_ERR("Timer debug failed.\n"); + exit(EXIT_FAILURE); } if (odp_term_local()) { - printf("Local term failed.\n"); - return -1; + ODPH_ERR("Local term failed.\n"); + exit(EXIT_FAILURE); } if (odp_term_global(inst)) { - printf("Global term failed.\n"); - return -1; + ODPH_ERR("Global term failed.\n"); + exit(EXIT_FAILURE); } return 0; diff --git a/example/m4/configure.m4 b/example/m4/configure.m4 index a1668e2b3..b02fd72a5 100644 --- a/example/m4/configure.m4 +++ b/example/m4/configure.m4 @@ -20,6 +20,7 @@ AC_ARG_ENABLE([test-example], AM_CONDITIONAL([test_example], [test x$test_example = xyes ]) AC_CONFIG_FILES([example/classifier/Makefile + example/cli/Makefile example/debug/Makefile example/generator/Makefile example/hello/Makefile diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c index cd790a181..cafe362a7 100644 --- a/example/timer/odp_timer_accuracy.c +++ b/example/timer/odp_timer_accuracy.c @@ -1,5 +1,5 @@ /* Copyright (c) 2018, Linaro Limited - * Copyright (c) 2019, Nokia + * Copyright (c) 2019-2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -51,6 +51,7 @@ typedef struct test_global_t { struct { unsigned long long period_ns; unsigned long long res_ns; + unsigned long long res_hz; unsigned long long offset_ns; unsigned long long max_tmo_ns; unsigned long long num; @@ -89,7 +90,9 @@ static void print_usage(void) "\n" "OPTIONS:\n" " -p, --period <nsec> Timeout period in nsec. Default: 200 msec\n" - " -r, --resolution <nsec> Timeout resolution in nsec. Default: period / 10\n" + " -r, --res_ns <nsec> Timeout resolution in nsec. Default: period / 10\n" + " -R, --res_hz <hertz> Timeout resolution in hertz. Note: resolution can be set\n" + " either in nsec or hertz (not both). Default: 0\n" " -f, --first <nsec> First timer offset in nsec. Default: 300 msec\n" " -x, --max_tmo <nsec> Maximum timeout in nsec. When 0, max tmo is calculated from other options. Default: 0\n" " -n, --num <number> Number of timeout periods. Default: 50\n" @@ -114,7 +117,8 @@ static int parse_options(int argc, char *argv[], test_global_t *test_global) int opt, long_index; const struct option longopts[] = { {"period", required_argument, NULL, 'p'}, - {"resolution", required_argument, NULL, 'r'}, + {"res_ns", required_argument, NULL, 'r'}, + {"res_hz", required_argument, NULL, 'R'}, {"first", required_argument, NULL, 'f'}, {"max_tmo", required_argument, NULL, 'x'}, {"num", required_argument, NULL, 'n'}, @@ -128,11 +132,12 @@ static int parse_options(int argc, char *argv[], test_global_t *test_global) {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; - const char *shortopts = "+p:r:f:x:n:b:g:m:o:e:s:ih"; + const char *shortopts = "+p:r:R:f:x:n:b:g:m:o:e:s:ih"; int ret = 0; test_global->opt.period_ns = 200 * ODP_TIME_MSEC_IN_NS; test_global->opt.res_ns = 0; + test_global->opt.res_hz = 0; test_global->opt.offset_ns = 300 * ODP_TIME_MSEC_IN_NS; test_global->opt.max_tmo_ns = 0; test_global->opt.num = 50; @@ -157,6 +162,9 @@ static int parse_options(int argc, char *argv[], test_global_t *test_global) case 'r': test_global->opt.res_ns = strtoull(optarg, NULL, 0); break; + case 'R': + test_global->opt.res_hz = strtoull(optarg, NULL, 0); + break; case 'f': test_global->opt.offset_ns = strtoull(optarg, NULL, 0); break; @@ -200,7 +208,8 @@ static int parse_options(int argc, char *argv[], test_global_t *test_global) } } - if (test_global->opt.res_ns == 0) + /* Default resolution */ + if (test_global->opt.res_ns == 0 && test_global->opt.res_hz == 0) test_global->opt.res_ns = test_global->opt.period_ns / 10; test_global->tot_timers = test_global->opt.num * test_global->opt.burst; @@ -224,7 +233,8 @@ static int start_timers(test_global_t *test_global) odp_queue_t queue; odp_queue_param_t queue_param; uint64_t tick, start_tick; - uint64_t period_ns, res_ns, start_ns, nsec, res_capa, offset_ns; + uint64_t period_ns, res_ns, res_hz, start_ns, nsec, offset_ns; + uint64_t max_res_ns, max_res_hz; odp_event_t event; odp_timeout_t timeout; odp_timer_set_t ret; @@ -298,22 +308,39 @@ static int start_timers(test_global_t *test_global) return -1; } - res_capa = timer_capa.highest_res_ns; + max_res_ns = timer_capa.max_res.res_ns; + max_res_hz = timer_capa.max_res.res_hz; offset_ns = test_global->opt.offset_ns; - res_ns = test_global->opt.res_ns; - if (res_ns < res_capa) { - printf("Resolution %" PRIu64 " nsec too high. " - "Highest resolution %" PRIu64 " nsec. " + if (test_global->opt.res_ns) { + res_ns = test_global->opt.res_ns; + res_hz = 0; + } else { + res_ns = 0; + res_hz = test_global->opt.res_hz; + } + + if (res_ns && res_ns < max_res_ns) { + printf("Resolution %" PRIu64 " nsec too high. Highest resolution %" PRIu64 " nsec. " "Default resolution is period / 10.\n\n", - res_ns, res_capa); + res_ns, max_res_ns); + return -1; + } + + if (res_hz && res_hz > max_res_hz) { + printf("Resolution %" PRIu64 " hz too high. Highest resolution %" PRIu64 " hz. " + "Default resolution is period / 10.\n\n", + res_hz, max_res_hz); return -1; } memset(&timer_param, 0, sizeof(odp_timer_pool_param_t)); - timer_param.res_ns = res_ns; + if (res_ns) + timer_param.res_ns = res_ns; + else + timer_param.res_hz = res_hz; if (mode == 0) { timer_param.min_tmo = offset_ns / 2; @@ -339,7 +366,8 @@ static int start_timers(test_global_t *test_global) printf("\nTest parameters:\n"); printf(" clock source: %i\n", test_global->opt.clk_src); - printf(" resolution capa: %" PRIu64 " nsec\n", res_capa); + printf(" max res nsec: %" PRIu64 "\n", max_res_ns); + printf(" max res hertz: %" PRIu64 "\n", max_res_hz); printf(" max timers capa: %" PRIu32 "\n", timer_capa.max_timers); printf(" mode: %i\n", mode); printf(" restart retries: %i\n", test_global->opt.early_retry); @@ -347,7 +375,10 @@ static int start_timers(test_global_t *test_global) printf(" log file: %s\n", test_global->filename); printf(" start offset: %" PRIu64 " nsec\n", offset_ns); printf(" period: %" PRIu64 " nsec\n", period_ns); - printf(" resolution: %" PRIu64 " nsec\n", timer_param.res_ns); + if (res_ns) + printf(" resolution: %" PRIu64 " nsec\n", res_ns); + else + printf(" resolution: %" PRIu64 " hz\n", res_hz); printf(" min timeout: %" PRIu64 " nsec\n", timer_param.min_tmo); printf(" max timeout: %" PRIu64 " nsec\n", timer_param.max_tmo); printf(" num timeout: %" PRIu64 "\n", num_tmo); @@ -494,11 +525,14 @@ static void print_stat(test_global_t *test_global) { uint64_t i; uint64_t tot_timers = test_global->tot_timers; - uint64_t res_ns = test_global->opt.res_ns; test_stat_t *stat = &test_global->stat; test_log_t *log = test_global->log; double ave_after = 0.0; double ave_before = 0.0; + double res_ns = test_global->opt.res_ns; + + if (test_global->opt.res_ns == 0) + res_ns = 1000000000.0 / test_global->opt.res_hz; if (stat->num_after) ave_after = (double)stat->nsec_after_sum / stat->num_after; |