aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
Diffstat (limited to 'example')
-rw-r--r--example/Makefile.am4
-rw-r--r--example/cli/.gitignore3
-rw-r--r--example/cli/Makefile.am31
-rw-r--r--example/cli/odp_cli.c176
-rwxr-xr-xexample/cli/odp_cli_run.sh9
-rw-r--r--example/debug/odp_debug.c331
-rw-r--r--example/m4/configure.m41
-rw-r--r--example/timer/odp_timer_accuracy.c66
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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;