aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2024-06-05 13:51:39 +0300
committerGitHub <noreply@github.com>2024-06-05 13:51:39 +0300
commit616034b9c9c789923f7ebe7f1c6d014c4ce8a5d2 (patch)
treedd1b579c93404d2d98b78944bbdf8313ec499bee /example
parent8063101c4fac56e16c5a2bb9843f2fd9c5acbfd7 (diff)
parent87913e636da621d47a8d3bc91fbe131abc09c294 (diff)
Merge ODP linux-generic v1.45.0.0 into linux-dpdk.
Diffstat (limited to 'example')
-rw-r--r--example/Makefile.am2
-rw-r--r--example/classifier/odp_classifier.c48
-rw-r--r--example/cli/odp_cli.c15
-rw-r--r--example/generator/.gitignore2
-rw-r--r--example/generator/Makefile.am34
-rwxr-xr-xexample/generator/generator_run.sh29
-rw-r--r--example/generator/odp_generator.c1760
-rw-r--r--example/ipfragreass/odp_ipfragreass_reassemble.c2
-rw-r--r--example/ipsec_api/odp_ipsec.c7
-rw-r--r--example/ipsec_crypto/odp_ipsec.c7
-rw-r--r--example/ipsec_crypto/odp_ipsec_fwd_db.c3
-rw-r--r--example/ipsec_crypto/odp_ipsec_misc.h8
-rw-r--r--example/ipsec_crypto/odp_ipsec_stream.c25
-rw-r--r--example/ipsec_crypto/odp_ipsec_stream.h7
-rw-r--r--example/l2fwd/README14
l---------example/l2fwd/odp_l2fwd.c1
-rw-r--r--example/l2fwd_simple/odp_l2fwd_simple.c16
-rw-r--r--example/l3fwd/odp_l3fwd_db.c3
-rw-r--r--example/m4/configure.m42
-rw-r--r--example/simple_pipeline/odp_simple_pipeline.c3
-rw-r--r--example/sysinfo/odp_sysinfo.c94
-rw-r--r--example/time/.gitignore1
-rw-r--r--example/time/Makefile.am9
-rw-r--r--example/time/odp_time_global_test.c397
-rw-r--r--example/timer/.gitignore2
-rw-r--r--example/timer/Makefile.am13
-rw-r--r--example/timer/odp_timer_accuracy.c1435
-rwxr-xr-xexample/timer/odp_timer_accuracy_run.sh7
-rw-r--r--example/timer/odp_timer_test.c569
-rw-r--r--example/traffic_mgmt/odp_traffic_mgmt.c6
30 files changed, 192 insertions, 4329 deletions
diff --git a/example/Makefile.am b/example/Makefile.am
index d6d242cf9..2ef6abd9d 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -1,6 +1,5 @@
SUBDIRS = classifier \
debug \
- generator \
hello \
ipsec_api \
ipsec_crypto \
@@ -11,7 +10,6 @@ SUBDIRS = classifier \
simple_pipeline \
switch \
sysinfo \
- time \
timer \
traffic_mgmt
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c
index f4218fd9c..d24224e6f 100644
--- a/example/classifier/odp_classifier.c
+++ b/example/classifier/odp_classifier.c
@@ -783,6 +783,8 @@ int main(int argc, char *argv[])
if (odp_pool_destroy(pool))
ODPH_ERR("err: odp_pool_destroy error\n");
+ free(args->if_name);
+
args_error:
odp_shm_free(shm);
@@ -977,16 +979,16 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
case ODP_PMR_TCP_SPORT:
/* :<port>:<mask> */
token = strtok(NULL, ":");
- strncpy(stats[policy_count].value, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].value, token,
+ DISPLAY_STRING_LEN);
value = strtoul(token, NULL, 0);
u16 = value;
u16 = odp_cpu_to_be_16(u16);
memcpy(stats[policy_count].rule.value_be, &u16, sizeof(u16));
token = strtok(NULL, ":");
- strncpy(stats[policy_count].mask, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].mask, token,
+ DISPLAY_STRING_LEN);
mask = strtoul(token, NULL, 0);
u16 = mask;
u16 = odp_cpu_to_be_16(u16);
@@ -999,8 +1001,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
case ODP_PMR_SIP_ADDR:
/* :<IP addr>:<mask> */
token = strtok(NULL, ":");
- strncpy(stats[policy_count].value, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].value, token,
+ DISPLAY_STRING_LEN);
if (odph_ipv4_addr_parse(&ip_addr, token)) {
ODPH_ERR("Bad IP address\n");
@@ -1011,8 +1013,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
memcpy(stats[policy_count].rule.value_be, &u32, sizeof(u32));
token = strtok(NULL, ":");
- strncpy(stats[policy_count].mask, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].mask, token,
+ DISPLAY_STRING_LEN);
mask = strtoul(token, NULL, 0);
u32 = mask;
u32 = odp_cpu_to_be_32(u32);
@@ -1023,8 +1025,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
case ODP_PMR_DMAC:
/* :<MAC addr>:<mask> */
token = strtok(NULL, ":");
- strncpy(stats[policy_count].value, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].value, token,
+ DISPLAY_STRING_LEN);
/* Replace hyphens in the MAC string with colons to be compatible with
* odph_eth_addr_parse(). */
@@ -1041,7 +1043,7 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
stats[policy_count].rule.val_sz = 6;
token = strtok(NULL, ":");
- strncpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].mask, token, DISPLAY_STRING_LEN);
mask_sz = parse_custom(token, stats[policy_count].rule.mask_be, ODPH_ETHADDR_LEN);
if (mask_sz != ODPH_ETHADDR_LEN) {
ODPH_ERR("Invalid mask. Provide mask without 0x prefix.\n");
@@ -1060,8 +1062,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
goto error;
token = strtok(NULL, ":");
- strncpy(stats[policy_count].value, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].value, token,
+ DISPLAY_STRING_LEN);
val_sz = parse_custom(token,
stats[policy_count].rule.value_be,
MAX_VAL_SIZE);
@@ -1070,8 +1072,8 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
goto error;
token = strtok(NULL, ":");
- strncpy(stats[policy_count].mask, token,
- DISPLAY_STRING_LEN - 1);
+ odph_strcpy(stats[policy_count].mask, token,
+ DISPLAY_STRING_LEN);
mask_sz = parse_custom(token,
stats[policy_count].rule.mask_be,
MAX_VAL_SIZE);
@@ -1091,13 +1093,13 @@ static int parse_pmr_policy(appl_args_t *appl_args, char *optarg)
if (cos1) {
stats[policy_count].has_src_cos = 1;
- strncpy(stats[policy_count].src_cos_name, cos0,
- ODP_COS_NAME_LEN - 1);
- strncpy(stats[policy_count].cos_name, cos1,
- ODP_COS_NAME_LEN - 1);
+ odph_strcpy(stats[policy_count].src_cos_name, cos0,
+ ODP_COS_NAME_LEN);
+ odph_strcpy(stats[policy_count].cos_name, cos1,
+ ODP_COS_NAME_LEN);
} else {
- strncpy(stats[policy_count].cos_name, cos0,
- ODP_COS_NAME_LEN - 1);
+ odph_strcpy(stats[policy_count].cos_name, cos0,
+ ODP_COS_NAME_LEN);
}
appl_args->policy_count++;
@@ -1281,9 +1283,7 @@ static int parse_args(int argc, char *argv[], appl_args_t *appl_args)
if (ret) {
usage();
-
- if (appl_args->if_name)
- free(appl_args->if_name);
+ free(appl_args->if_name);
}
/* reset optind from the getopt lib */
diff --git a/example/cli/odp_cli.c b/example/cli/odp_cli.c
index 381fc8a59..bc5dad960 100644
--- a/example/cli/odp_cli.c
+++ b/example/cli/odp_cli.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2021 Nokia
+ * Copyright (c) 2021-2024 Nokia
*/
/**
@@ -101,7 +101,7 @@ static int cli_server(void *arg ODP_UNUSED)
/* Run CLI server. */
if (odph_cli_run()) {
ODPH_ERR("odph_cli_run() failed.\n");
- exit(EXIT_FAILURE);
+ return -1;
}
return 0;
@@ -178,6 +178,7 @@ int main(int argc, char *argv[])
odph_thread_common_param_t thr_common;
odph_thread_param_t thr_param;
odph_thread_t thr_server;
+ odph_thread_join_result_t res;
if (odp_cpumask_default_control(&cpumask, 1) != 1) {
ODPH_ERR("Failed to get default CPU mask.\n");
@@ -199,7 +200,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- printf("CLI server started on %s:%d\n", cli_param.address,
+ printf("CLI server started on %s:%d.\n", cli_param.address,
cli_param.port);
/* Wait for the given number of seconds. */
@@ -215,11 +216,17 @@ int main(int argc, char *argv[])
}
/* Wait for server thread to exit. */
- if (odph_thread_join(&thr_server, 1) != 1) {
+ if (odph_thread_join_result(&thr_server, &res, 1) != 1) {
ODPH_ERR("Failed to join server thread.\n");
exit(EXIT_FAILURE);
}
+ if (res.is_sig || res.ret != 0) {
+ ODPH_ERR("Worker thread failure%s: %d.\n", res.is_sig ? " (signaled)" : "",
+ res.ret);
+ exit(EXIT_FAILURE);
+ }
+
/* Terminate CLI helper. */
if (odph_cli_term()) {
ODPH_ERR("CLI helper termination failed.\n");
diff --git a/example/generator/.gitignore b/example/generator/.gitignore
deleted file mode 100644
index 37364a254..000000000
--- a/example/generator/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-odp_generator
-pktio_env
diff --git a/example/generator/Makefile.am b/example/generator/Makefile.am
deleted file mode 100644
index c3c08a663..000000000
--- a/example/generator/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-include $(top_srcdir)/example/Makefile.inc
-
-bin_PROGRAMS = odp_generator
-
-odp_generator_SOURCES = odp_generator.c
-
-TEST_EXTENSIONS = .sh
-
-if test_example
-TESTS = generator_run.sh
-endif
-EXTRA_DIST = generator_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
- ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/generator/pktio_env \
- pktio_env
-clean-local:
- if [ "x$(srcdir)" != "x$(builddir)" ]; then \
- for f in $(EXTRA_DIST); do \
- rm -f $(builddir)/$$f; \
- done \
- fi
diff --git a/example/generator/generator_run.sh b/example/generator/generator_run.sh
deleted file mode 100755
index ca69b53bd..000000000
--- a/example/generator/generator_run.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-#
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2020 Marvell
-#
-
-if [ -f ./pktio_env ]; then
- . ./pktio_env
-else
- echo "BUG: unable to find pktio_env!"
- echo "pktio_env has to be in current directory"
- exit 1
-fi
-
-setup_interfaces
-
-./odp_generator${EXEEXT} -w 1 -n 1 -I $IF0 -m u
-STATUS=$?
-
-if [ "$STATUS" -ne 0 ]; then
- echo "Error: status was: $STATUS, expected 0"
- exit 1
-fi
-
-validate_result
-
-cleanup_interfaces
-
-exit 0
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
deleted file mode 100644
index 6ec19d0ea..000000000
--- a/example/generator/odp_generator.c
+++ /dev/null
@@ -1,1760 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2014-2018 Linaro Limited
- */
-
-/**
- * @example odp_generator.c
- *
- * Traffic generator and loopback demo application
- *
- * @cond _ODP_HIDE_FROM_DOXYGEN_
- */
-
-/** enable strtok */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <time.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/time.h>
-#include <signal.h>
-
-#include <odp_api.h>
-
-#include <odp/helper/odph_api.h>
-
-/* Max number of workers */
-#define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
-#define POOL_NUM_PKT 2048 /* Number of packets in packet pool */
-#define POOL_PKT_LEN 1856 /* Max packet length */
-#define DEFAULT_PKT_INTERVAL 1000 /* Interval between each packet */
-#define DEFAULT_UDP_TX_BURST 16
-#define MAX_UDP_TX_BURST 512
-#define DEFAULT_RX_BURST 32
-#define MAX_RX_BURST 512
-#define STATS_INTERVAL 10 /* Interval between stats prints (sec) */
-
-#define APPL_MODE_UDP 0 /**< UDP mode */
-#define APPL_MODE_PING 1 /**< ping mode */
-#define APPL_MODE_RCV 2 /**< receive mode */
-
-#define PING_THR_TX 0
-#define PING_THR_RX 1
-
-/** 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))
-
-/**
- * Interfaces
- */
-
-typedef struct {
- odp_pktio_t pktio;
- odp_pktio_config_t config;
- odp_pktout_queue_t pktout[MAX_WORKERS];
- uint32_t pktout_count;
- odp_pktin_queue_t pktin[MAX_WORKERS];
- uint32_t pktin_count;
-} interface_t;
-
-/**
- * Parsed command line application arguments
- */
-typedef struct {
- int num_workers; /**< Number of worker thread */
- const char *mask; /**< CPU mask */
- int if_count; /**< Number of interfaces to be used */
- char **if_names; /**< Array of pointers to interface names */
- char *if_str; /**< Storage for interface names */
- odp_pool_t pool; /**< Pool for packet IO */
- odph_ethaddr_t srcmac; /**< src mac addr */
- odph_ethaddr_t dstmac; /**< dest mac addr */
- unsigned int srcip; /**< src ip addr */
- unsigned int dstip; /**< dest ip addr */
- uint16_t srcport; /**< src udp port */
- uint16_t srcport_end; /**< src udp end port */
- uint16_t dstport; /**< dest udp port */
- uint16_t dstport_end; /**< dest udp end port */
- 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 */
- int udp_tx_burst; /**< number of udp packets to send with one
- API call */
- int rx_burst; /**< number of packets to receive with one
- API call */
- odp_bool_t csum; /**< use platform csum support if available */
- odp_bool_t sched; /**< use scheduler API to receive packets */
-} appl_args_t;
-
-/**
- * counters
-*/
-typedef struct {
- uint64_t ctr_pkt_snd; /**< sent packets*/
- uint64_t ctr_pkt_snd_drop; /**< packets dropped in transmit */
-
- uint64_t ctr_pkt_rcv; /**< recv packets */
- uint64_t ctr_seq; /**< ip seq to be send */
- uint64_t ctr_udp_rcv; /**< udp packets */
- uint64_t ctr_icmp_reply_rcv; /**< icmp reply packets */
-} counters_t;
-
-/** UDP Packet processing function argument */
-typedef struct {
- odp_bool_t multi_flow;
- uint16_t srcport_crt;
- uint16_t srcport_start;
- uint16_t srcport_end;
- uint16_t dstport_crt;
- uint16_t dstport_start;
- uint16_t dstport_end;
-} udp_args_t;
-
-/** * Thread specific arguments
- */
-typedef struct {
- counters_t counters; /**< Packet counters */
- odp_bool_t stop; /**< Stop packet processing */
- union {
- struct {
- odp_pktout_queue_t pktout; /**< Packet output queue */
- odp_pktout_config_opt_t *pktout_cfg; /**< Packet output config*/
- udp_args_t udp_param; /**< UDP configuration */
- } tx;
- struct {
- odp_pktin_queue_t pktin; /**< Packet input queue */
- } rx;
- };
- odp_pool_t pool; /**< 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];
- /** Global arguments */
- int thread_cnt;
- int tx_burst_size;
- int rx_burst_size;
- /** Barrier to sync threads execution */
- odp_barrier_t barrier;
-} args_t;
-
-/** Global pointer to args */
-static args_t *args;
-
-/** Packet processing function types */
-typedef odp_packet_t (*setup_pkt_ref_fn_t)(odp_pool_t,
- odp_pktout_config_opt_t *);
-typedef int (*setup_pkt_fn_t)(odp_packet_t, odp_pktout_config_opt_t *,
- counters_t *, void *);
-
-/* 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 void print_global_stats(int num_workers);
-
-static void sig_handler(int signo ODP_UNUSED)
-{
- int i;
- if (args == NULL)
- return;
- for (i = 0; i < args->thread_cnt; i++)
- args->thread[i].stop = 1;
-}
-
-/**
- * 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)
-{
- unsigned int part1, part2, part3, part4;
- char tail = 0;
- int field;
-
- if (buf == NULL)
- return 0;
-
- field = sscanf(buf, "%u . %u . %u . %u %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 <= 255 && part2 <= 255 && part3 <= 255 && part4 <= 255) {
- if (paddr)
- *paddr = part1 << 24 | part2 << 16 | part3 << 8 | part4;
- return 1;
- }
-
- printf("not good ip %u:%u:%u:%u/n", part1, part2, part3, part4);
-
- return 0;
-}
-
-/**
- * Setup array of reference packets
- *
- * @param pool Packet pool
- * @param pktout_cfg Interface output configuration
- * @param pkt_ref_array Packet array
- * @param pkt_ref_array_size Packet array size
- * @param setup_ref Packet setup function
- * @return 0 success, -1 failed
-*/
-static int setup_pkt_ref_array(odp_pool_t pool,
- odp_pktout_config_opt_t *pktout_cfg,
- odp_packet_t *pkt_ref_array,
- int pkt_ref_array_size,
- setup_pkt_ref_fn_t setup_ref)
-{
- int i;
-
- for (i = 0; i < pkt_ref_array_size; i++) {
- pkt_ref_array[i] = (*setup_ref)(pool, pktout_cfg);
- if (pkt_ref_array[i] == ODP_PACKET_INVALID)
- break;
- }
-
- if (i < pkt_ref_array_size) {
- odp_packet_free_multi(pkt_ref_array, i);
- return -1;
- }
- return 0;
-}
-
-/**
- * Setup array of packets
- *
- * @param pktout_cfg Interface output configuration
- * @param pkt_ref_array Reference packet array
- * @param pkt_array Packet array
- * @param pkt_array_size Packet array size
- * @param setup_pkt Packet setup function
- * @return 0 success, -1 failed
-*/
-static int setup_pkt_array(odp_pktout_config_opt_t *pktout_cfg,
- counters_t *counters,
- odp_packet_t *pkt_ref_array,
- odp_packet_t *pkt_array,
- int pkt_array_size,
- setup_pkt_fn_t setup_pkt,
- void *setup_pkt_arg)
-{
- int i;
-
- for (i = 0; i < pkt_array_size; i++) {
- if ((*setup_pkt)(pkt_ref_array[i], pktout_cfg, counters,
- setup_pkt_arg))
- break;
-
- pkt_array[i] = odp_packet_ref_static(pkt_ref_array[i]);
- if (pkt_array[i] == ODP_PACKET_INVALID)
- break;
- }
- if (i < pkt_array_size) {
- if (i)
- odp_packet_free_multi(pkt_array, i - 1);
-
- return -1;
- }
- return 0;
-}
-
-/**
- * set up an udp packet reference
- *
- * @param pool Buffer pool to create packet in
- * @param pktout_cfg Interface output configuration
- *
- *
- * @retval Handle of created packet
- * @retval ODP_PACKET_INVALID Packet could not be created
- *
- */
-static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool,
- odp_pktout_config_opt_t *pktout_cfg)
-{
- odp_packet_t pkt;
- char *buf;
- odph_ethhdr_t *eth;
- odph_ipv4hdr_t *ip;
- odph_udphdr_t *udp;
-
- pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_UDPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
-
- if (pkt == ODP_PACKET_INVALID)
- return pkt;
-
- buf = odp_packet_data(pkt);
-
- /* ether */
- odp_packet_l2_offset_set(pkt, 0);
- eth = (odph_ethhdr_t *)buf;
- memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
- memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
- eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
-
- /* ip */
- odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
- odp_packet_has_ipv4_set(pkt, 1);
- ip = (odph_ipv4hdr_t *)(buf + ODPH_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 = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
- ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN +
- ODPH_IPV4HDR_LEN);
- ip->proto = ODPH_IPPROTO_UDP;
- ip->id = 0;
- ip->ttl = 64;
- ip->chksum = 0;
-
- /* udp */
- odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
- odp_packet_has_udp_set(pkt, 1);
- udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
- udp->src_port = odp_cpu_to_be_16(args->appl.srcport);
- udp->dst_port = odp_cpu_to_be_16(args->appl.dstport);
- udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN);
- if (!pktout_cfg->bit.udp_chksum) {
- udp->chksum = 0;
- udp->chksum = odph_ipv4_udp_chksum(pkt);
- }
-
- return pkt;
-}
-
-/**
- * set up an udp packet
- *
- * @param pkt Reference UDP packet
- * @param pktout_cfg Interface output configuration
- *
- * @return Success/Failed
- * @retval 0 on success, -1 on fail
- */
-static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg,
- counters_t *counters, void *arg)
-{
- char *buf;
- odph_ipv4hdr_t *ip;
- unsigned short seq;
- udp_args_t *udp_arg = (udp_args_t *)arg;
-
- buf = (char *)odp_packet_data(pkt);
-
- /*Update IP ID and checksum*/
- ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
- seq = counters->ctr_seq % 0xFFFF;
- counters->ctr_seq++;
- ip->id = odp_cpu_to_be_16(seq);
- if (!pktout_cfg->bit.ipv4_chksum) {
- ip->chksum = 0;
- ip->chksum = ~odp_chksum_ones_comp16(ip, ODPH_IPV4HDR_LEN);
- }
-
- if (udp_arg->multi_flow) {
- odph_udphdr_t *udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN +
- ODPH_IPV4HDR_LEN);
-
- if (udp_arg->srcport_start != udp_arg->srcport_end) {
- udp->src_port = odp_cpu_to_be_16(udp_arg->srcport_crt);
- if (udp_arg->srcport_crt >= udp_arg->srcport_end)
- udp_arg->srcport_crt = udp_arg->srcport_start;
- else
- udp_arg->srcport_crt++;
- }
- if (udp_arg->dstport_start != udp_arg->dstport_end) {
- udp->dst_port = odp_cpu_to_be_16(udp_arg->dstport_crt);
- if (udp_arg->dstport_crt >= udp_arg->dstport_end)
- udp_arg->dstport_crt = udp_arg->dstport_start;
- else
- udp_arg->dstport_crt++;
- }
-
- udp->chksum = 0;
- }
-
- if (pktout_cfg->bit.ipv4_chksum || pktout_cfg->bit.udp_chksum) {
- odp_packet_l2_offset_set(pkt, 0);
- odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
- odp_packet_has_ipv4_set(pkt, 1);
- odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
- ODPH_IPV4HDR_LEN);
- odp_packet_has_udp_set(pkt, 1);
- }
- return 0;
-}
-
-/**
- * Set up an icmp packet reference
- *
- * @param pool Buffer pool to create packet in
- * @param pktout_cfg Interface output configuration
- *
- * @return Handle of created packet
- * @retval ODP_PACKET_INVALID Packet could not be created
- */
-static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool,
- odp_pktout_config_opt_t *pktout_cfg)
-{
- odp_packet_t pkt;
- char *buf;
- odph_ethhdr_t *eth;
- odph_ipv4hdr_t *ip;
- odph_icmphdr_t *icmp;
-
- (void)pktout_cfg;
-
- args->appl.payload = 56;
- pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
-
- if (pkt == ODP_PACKET_INVALID)
- return pkt;
-
- buf = odp_packet_data(pkt);
-
- /* ether */
- odp_packet_l2_offset_set(pkt, 0);
- eth = (odph_ethhdr_t *)buf;
- memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN);
- memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN);
- eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
- /* ip */
- odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
- ip = (odph_ipv4hdr_t *)(buf + ODPH_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 = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
- ip->ttl = 64;
- ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_ICMPHDR_LEN +
- ODPH_IPV4HDR_LEN);
- ip->proto = ODPH_IPPROTO_ICMPV4;
- ip->id = 0;
- ip->chksum = 0;
-
- /* icmp */
- icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
- icmp->type = ODPH_ICMP_ECHO;
- icmp->code = 0;
- icmp->un.echo.id = 0;
- icmp->un.echo.sequence = 0;
- icmp->chksum = 0;
-
- return pkt;
-}
-
-/**
- * Set up an icmp packet
- *
- * @param pkt Reference ICMP packet
- * @param pktout_cfg Interface output configuration
- *
- * @return Success/Failed
- * @retval 0 on success, -1 on fail
- */
-static int setup_icmp_pkt(odp_packet_t pkt,
- odp_pktout_config_opt_t *pktout_cfg,
- counters_t *counters, void *arg ODP_UNUSED)
-{
- char *buf;
- odph_ipv4hdr_t *ip;
- odph_icmphdr_t *icmp;
- uint64_t tval;
- uint8_t *tval_d;
- unsigned short seq;
-
- buf = (char *)odp_packet_data(pkt);
-
- /* ip */
- ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
- seq = counters->ctr_seq % 0xffff;
- counters->ctr_seq++;
- ip->id = odp_cpu_to_be_16(seq);
- if (!pktout_cfg->bit.ipv4_chksum) {
- ip->chksum = 0;
- ip->chksum = ~odp_chksum_ones_comp16(ip, ODPH_IPV4HDR_LEN);
- }
-
- /* icmp */
- icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
- icmp->un.echo.sequence = ip->id;
-
- tval_d = (uint8_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN +
- ODPH_ICMPHDR_LEN);
- tval = odp_time_to_ns(odp_time_local());
- memcpy(tval_d, &tval, sizeof(uint64_t));
-
- icmp->chksum = 0;
- icmp->chksum = ~odp_chksum_ones_comp16(icmp, args->appl.payload +
- ODPH_ICMPHDR_LEN);
-
- if (pktout_cfg->bit.ipv4_chksum) {
- odp_packet_l2_offset_set(pkt, 0);
- odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
- odp_packet_has_ipv4_set(pkt, 1);
- odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
- ODPH_IPV4HDR_LEN);
- }
-
- return 0;
-}
-
-/**
- * Create a pktio object
- *
- * @param dev Name of device to open
- * @param pool Pool to associate with device for packet RX/TX
- *
- * @return The handle of the created pktio object.
- * @warning This routine aborts if the create is unsuccessful.
- */
-static int create_pktio(const char *dev, odp_pool_t pool,
- uint32_t num_rx_queues,
- uint32_t num_tx_queues,
- interface_t *itf)
-{
- odp_pktio_capability_t capa;
- int ret;
- odp_pktio_param_t pktio_param;
- odp_pktin_queue_param_t pktin_param;
- odp_pktout_queue_param_t pktout_param;
- odp_pktio_op_mode_t pktout_mode, pktin_mode;
- odp_bool_t sched = args->appl.sched;
-
- odp_pktio_param_init(&pktio_param);
- pktio_param.in_mode = num_rx_queues ?
- (sched ? ODP_PKTIN_MODE_SCHED : ODP_PKTIN_MODE_DIRECT) :
- ODP_PKTIN_MODE_DISABLED;
- pktio_param.out_mode = num_tx_queues ? ODP_PKTOUT_MODE_DIRECT :
- ODP_PKTOUT_MODE_DISABLED;
-
- /* Open a packet IO instance */
- itf->pktio = odp_pktio_open(dev, pool, &pktio_param);
-
- if (itf->pktio == ODP_PKTIO_INVALID) {
- ODPH_ERR("Error: pktio create failed for %s\n", dev);
- return -1;
- }
-
- if (odp_pktio_capability(itf->pktio, &capa)) {
- ODPH_ERR("Error: Failed to get interface capabilities %s\n",
- dev);
- return -1;
- }
- odp_pktio_config_init(&itf->config);
- if (args->appl.csum) {
- itf->config.pktin.bit.ipv4_chksum =
- capa.config.pktin.bit.ipv4_chksum;
- itf->config.pktin.bit.udp_chksum =
- capa.config.pktin.bit.udp_chksum;
- itf->config.pktin.bit.drop_ipv4_err =
- capa.config.pktin.bit.drop_ipv4_err;
- itf->config.pktin.bit.drop_udp_err =
- capa.config.pktin.bit.drop_udp_err;
-
- itf->config.pktout.bit.ipv4_chksum_ena =
- capa.config.pktout.bit.ipv4_chksum_ena;
- itf->config.pktout.bit.udp_chksum_ena =
- capa.config.pktout.bit.udp_chksum_ena;
- itf->config.pktout.bit.ipv4_chksum =
- capa.config.pktout.bit.ipv4_chksum;
- itf->config.pktout.bit.udp_chksum =
- capa.config.pktout.bit.udp_chksum;
- } else { /* explicit disable */
- itf->config.pktin.bit.ipv4_chksum = 0;
- itf->config.pktin.bit.udp_chksum = 0;
- itf->config.pktout.bit.ipv4_chksum_ena = 0;
- itf->config.pktout.bit.udp_chksum_ena = 0;
- itf->config.pktout.bit.ipv4_chksum = 0;
- itf->config.pktout.bit.udp_chksum = 0;
- }
-
- itf->config.parser.layer = ODP_PROTO_LAYER_L2;
- if (itf->config.pktin.bit.udp_chksum)
- itf->config.parser.layer = ODP_PROTO_LAYER_L4;
- else if (itf->config.pktin.bit.ipv4_chksum)
- itf->config.parser.layer = ODP_PROTO_LAYER_L3;
-
- if (odp_pktio_config(itf->pktio, &itf->config)) {
- ODPH_ERR("Error: Failed to set interface configuration %s\n",
- dev);
- return -1;
- }
-
- if (num_rx_queues) {
- pktin_mode = ODP_PKTIO_OP_MT_UNSAFE;
- if (num_rx_queues > capa.max_input_queues) {
- num_rx_queues = capa.max_input_queues;
- pktin_mode = ODP_PKTIO_OP_MT;
- ODPH_DBG("Warning: Force RX multithread safe mode "
- "(slower)on %s\n", dev);
- }
-
- odp_pktin_queue_param_init(&pktin_param);
- pktin_param.num_queues = num_rx_queues;
- pktin_param.op_mode = pktin_mode;
- if (sched)
- pktin_param.queue_param.sched.sync =
- ODP_SCHED_SYNC_ATOMIC;
-
- if (odp_pktin_queue_config(itf->pktio, &pktin_param)) {
- ODPH_ERR("Error: pktin queue config failed for %s\n",
- dev);
- return -1;
- }
- }
-
- if (num_tx_queues) {
- pktout_mode = ODP_PKTIO_OP_MT_UNSAFE;
- if (num_tx_queues > capa.max_output_queues) {
- num_tx_queues = capa.max_output_queues;
- pktout_mode = ODP_PKTIO_OP_MT;
- ODPH_DBG("Warning: Force TX multithread safe mode "
- "(slower) on %s\n", dev);
- }
-
- odp_pktout_queue_param_init(&pktout_param);
- pktout_param.num_queues = num_tx_queues;
- pktout_param.op_mode = pktout_mode;
-
- if (odp_pktout_queue_config(itf->pktio, &pktout_param)) {
- ODPH_ERR("Error: pktout queue config failed for %s\n",
- dev);
- return -1;
- }
- }
-
- ret = odp_pktio_start(itf->pktio);
- if (ret)
- ODPH_ABORT("Error: unable to start %s\n", dev);
-
- itf->pktout_count = num_tx_queues;
- if (itf->pktout_count &&
- odp_pktout_queue(itf->pktio, itf->pktout, itf->pktout_count) !=
- (int)itf->pktout_count) {
- ODPH_ERR("Error: failed to get output queues for %s\n", dev);
- return -1;
- }
-
- itf->pktin_count = num_rx_queues;
- if (!sched && itf->pktin_count &&
- odp_pktin_queue(itf->pktio, itf->pktin, itf->pktin_count) !=
- (int)itf->pktin_count) {
- ODPH_ERR("Error: failed to get input queues for %s\n", dev);
- return -1;
- }
-
- printf(" created pktio:%02" PRIu64
- ", dev:%s, queue mode (ATOMIC queues)\n"
- " default pktio%02" PRIu64 "\n",
- odp_pktio_to_u64(itf->pktio), dev,
- odp_pktio_to_u64(itf->pktio));
- fflush(NULL);
-
- return 0;
-}
-
-/**
- * Packet IO loopback worker thread using ODP queues
- *
- * @param arg thread arguments of type 'thread_args_t *'
- */
-
-static int gen_send_thread(void *arg)
-{
- int thr;
- int ret = 0;
- thread_args_t *thr_args;
- odp_pktout_queue_t pktout;
- odp_pktout_config_opt_t *pktout_cfg;
- odp_packet_t pkt_ref_array[MAX_UDP_TX_BURST];
- odp_packet_t pkt_array[MAX_UDP_TX_BURST];
- int pkt_array_size, seq_step;
- int burst_start, burst_size;
- setup_pkt_ref_fn_t setup_pkt_ref = NULL;
- setup_pkt_fn_t setup_pkt = NULL;
- void *setup_pkt_arg = NULL;
- counters_t *counters;
- uint64_t pkt_count_max = 0;
-
- thr = odp_thread_id();
- thr_args = arg;
- pktout = thr_args->tx.pktout;
- pktout_cfg = thr_args->tx.pktout_cfg;
- counters = &thr_args->counters;
-
- /* Create reference packets*/
- if (args->appl.mode == APPL_MODE_UDP) {
- setup_pkt_ref = setup_udp_pkt_ref;
- setup_pkt = setup_udp_pkt;
- seq_step = args->tx_burst_size * (args->thread_cnt - 1);
- if (args->appl.number != -1)
- pkt_count_max = args->appl.number / args->thread_cnt +
- (args->appl.number % args->thread_cnt ? 1 : 0);
- setup_pkt_arg = &thr_args->tx.udp_param;
- } else if (args->appl.mode == APPL_MODE_PING) {
- setup_pkt_ref = setup_icmp_pkt_ref;
- setup_pkt = setup_icmp_pkt;
- seq_step = 0;
- if (args->appl.number != -1)
- pkt_count_max = args->appl.number;
- } else {
- ODPH_ERR(" [%02i] Error: invalid processing mode %d\n", thr,
- args->appl.mode);
- return -1;
- }
- pkt_array_size = args->tx_burst_size;
-
- if (setup_pkt_ref_array(thr_args->pool, pktout_cfg,
- pkt_ref_array, pkt_array_size,
- setup_pkt_ref)) {
- ODPH_ERR("[%02i] Error: failed to create reference packets\n",
- thr);
- return -1;
- }
-
- printf(" [%02i] created mode: SEND\n", thr);
-
- odp_barrier_wait(&args->barrier);
-
- for (;;) {
- if (thr_args->stop)
- break;
-
- if (pkt_count_max && counters->ctr_pkt_snd > pkt_count_max) {
- sleep(1); /* wait for stop command */
- continue;
- }
-
- /* Setup TX burst*/
- if (setup_pkt_array(pktout_cfg, counters,
- pkt_ref_array, pkt_array,
- pkt_array_size, setup_pkt, setup_pkt_arg)) {
- ODPH_ERR("[%02i] Error: failed to setup packets\n",
- thr);
- break;
- }
-
- /* Send TX burst*/
- for (burst_start = 0, burst_size = pkt_array_size;;) {
- ret = odp_pktout_send(pktout, &pkt_array[burst_start],
- burst_size);
- if (ret == burst_size) {
- burst_size = 0;
- break;
- } else if (ret >= 0 && ret < burst_size) {
- thr_args->counters.ctr_pkt_snd_drop +=
- burst_size - ret;
-
- burst_start += ret;
- burst_size -= ret;
- continue;
- }
- ODPH_ERR(" [%02i] packet send failed\n", thr);
- odp_packet_free_multi(&pkt_array[burst_start],
- burst_size);
- break;
- }
-
- counters->ctr_pkt_snd += pkt_array_size - burst_size;
-
- if (args->appl.interval != 0)
- odp_time_wait_ns((uint64_t)args->appl.interval *
- ODP_TIME_MSEC_IN_NS);
- counters->ctr_seq += seq_step;
- }
-
- odp_packet_free_multi(pkt_ref_array, pkt_array_size);
-
- return 0;
-}
-
-/**
- * Process icmp packets
- *
- * @param thr worker id
- * @param thr_args worker argument
- * @param icmp icmp header address
- */
-
-static void process_icmp_pkt(int thr, thread_args_t *thr_args,
- uint8_t *_icmp)
-{
- uint64_t trecv;
- uint64_t tsend;
- uint64_t rtt_ms, rtt_us;
- odph_icmphdr_t *icmp = (odph_icmphdr_t *)_icmp;
-
- if (icmp->type == ODPH_ICMP_ECHOREPLY) {
- thr_args->counters.ctr_icmp_reply_rcv++;
-
- memcpy(&tsend, (uint8_t *)icmp + ODPH_ICMPHDR_LEN,
- sizeof(uint64_t));
- trecv = odp_time_to_ns(odp_time_local());
- rtt_ms = (trecv - tsend) / ODP_TIME_MSEC_IN_NS;
- rtt_us = (trecv - tsend) / ODP_TIME_USEC_IN_NS -
- 1000 * rtt_ms;
- printf(" [%02i] ICMP Echo Reply seq %d time %"
- PRIu64 ".%.03" PRIu64" ms\n", thr,
- odp_be_to_cpu_16(icmp->un.echo.sequence),
- rtt_ms, rtt_us);
- } else if (icmp->type == ODPH_ICMP_ECHO) {
- printf(" [%02i] ICMP Echo Request\n", thr);
- }
-}
-
-/**
- * Process odp packets
- *
- * @param thr worker id
- * @param thr_args worker argument
- * @param pkt_tbl packets to be print
- * @param len packet number
- */
-static void process_pkts(int thr, thread_args_t *thr_args,
- odp_packet_t pkt_tbl[], unsigned len)
-{
- odp_packet_t pkt;
- uint32_t left, offset, i;
- odph_ipv4hdr_t *ip;
-
- for (i = 0; i < len; ++i) {
- pkt = pkt_tbl[i];
-
- /* Drop packets with errors */
- if (odp_unlikely(odp_packet_has_error(pkt)))
- continue;
-
- offset = odp_packet_l3_offset(pkt);
- left = odp_packet_len(pkt) - offset;
-
- if (left < sizeof(odph_ipv4hdr_t))
- continue;
-
- ip = (odph_ipv4hdr_t *)((uint8_t *)odp_packet_data(pkt) +
- offset);
-
- /* only ip pkts */
- if (ODPH_IPV4HDR_VER(ip->ver_ihl) != ODPH_IPV4)
- continue;
-
- thr_args->counters.ctr_pkt_rcv++;
-
- /* udp */
- if (ip->proto == ODPH_IPPROTO_UDP) {
- thr_args->counters.ctr_udp_rcv++;
- } else if (ip->proto == ODPH_IPPROTO_ICMPV4) {
- uint32_t l3_size = ODPH_IPV4HDR_IHL(ip->ver_ihl) * 4;
-
- offset += l3_size;
- left -= l3_size;
-
- if (left < sizeof(odph_icmphdr_t))
- continue;
-
- process_icmp_pkt(thr, thr_args,
- (uint8_t *)odp_packet_data(pkt) +
- offset);
- }
- }
-}
-
-/**
- * Scheduler receive function
- *
- * @param arg thread arguments of type 'thread_args_t *'
- */
-static int gen_recv_thread(void *arg)
-{
- int thr;
- thread_args_t *thr_args;
- odp_packet_t pkts[MAX_RX_BURST];
- odp_event_t events[MAX_RX_BURST], ev;
- int pkt_cnt, ev_cnt, i;
- int burst_size;
-
- thr = odp_thread_id();
- thr_args = (thread_args_t *)arg;
- burst_size = args->rx_burst_size;
-
- printf(" [%02i] created mode: RECEIVE SCHEDULER\n", thr);
- odp_barrier_wait(&args->barrier);
-
- for (;;) {
- if (thr_args->stop)
- break;
-
- /* Use schedule to get buf from any input queue */
- ev_cnt = odp_schedule_multi(NULL, ODP_SCHED_NO_WAIT,
- events, burst_size);
- if (ev_cnt == 0)
- continue;
-
- for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) {
- ev = events[i];
-
- if (odp_event_type(ev) == ODP_EVENT_PACKET)
- pkts[pkt_cnt++] = odp_packet_from_event(ev);
- else
- odp_event_free(ev);
- }
-
- if (pkt_cnt) {
- process_pkts(thr, thr_args, pkts, pkt_cnt);
-
- odp_packet_free_multi(pkts, pkt_cnt);
- }
- }
-
- return 0;
-}
-
-/**
- * Direct receive function
- *
- * @param arg thread arguments of type 'thread_args_t *'
- */
-static int gen_recv_direct_thread(void *arg)
-{
- int thr;
- thread_args_t *thr_args;
- odp_packet_t pkts[MAX_RX_BURST];
- int pkt_cnt, burst_size;
- odp_pktin_queue_t pktin;
- uint64_t wait = odp_pktin_wait_time(ODP_TIME_SEC_IN_NS);
-
- thr = odp_thread_id();
- thr_args = (thread_args_t *)arg;
- pktin = thr_args->rx.pktin;
- burst_size = args->rx_burst_size;
-
- printf(" [%02i] created mode: RECEIVE\n", thr);
- odp_barrier_wait(&args->barrier);
-
- for (;;) {
- if (thr_args->stop)
- break;
-
- pkt_cnt = odp_pktin_recv_tmo(pktin, pkts, burst_size, wait);
-
- if (pkt_cnt > 0) {
- process_pkts(thr, thr_args, pkts, pkt_cnt);
-
- odp_packet_free_multi(pkts, pkt_cnt);
- } else if (pkt_cnt == 0) {
- continue;
- } else {
- break;
- }
- }
-
- return 0;
-}
-
-#define COUNTER_SUM(_c, _nw) \
-__extension__ ({ \
- int _itr; \
- uint64_t _result = 0; \
- \
- for (_itr = 0; _itr < _nw; _itr++) \
- _result += args->thread[_itr].counters.ctr_ ## _c; \
- \
- _result; \
-})
-
-static void garceful_stop_ping(void)
-{
- uint64_t snd, rcv;
-
- if (args->appl.mode != APPL_MODE_PING)
- return;
-
- while (args->appl.timeout >= 0) {
- snd = COUNTER_SUM(pkt_snd, 2);
- rcv = COUNTER_SUM(icmp_reply_rcv, 2);
- if (rcv >= snd)
- break;
-
- sleep(1);
- args->appl.timeout--;
- }
-}
-
-/**
- * printing verbose statistics
- *
- */
-static void print_global_stats(int num_workers)
-{
- odp_time_t cur, wait, next, left;
- uint64_t pkts_snd = 0, pkts_snd_prev = 0;
- uint64_t pps_snd = 0, maximum_pps_snd = 0;
- uint64_t pkts_rcv = 0, pkts_rcv_prev = 0;
- uint64_t pps_rcv = 0, maximum_pps_rcv = 0;
- uint64_t stall, pkts_snd_drop;
- int verbose_interval = STATS_INTERVAL, i;
- odp_thrmask_t thrd_mask;
-
- odp_barrier_wait(&args->barrier);
-
- wait = odp_time_local_from_ns(verbose_interval * ODP_TIME_SEC_IN_NS);
- next = odp_time_sum(odp_time_local(), wait);
-
- while (odp_thrmask_worker(&thrd_mask) == num_workers) {
- if (args->appl.mode != APPL_MODE_RCV &&
- args->appl.number != -1) {
- uint64_t cnt = COUNTER_SUM(pkt_snd, num_workers);
-
- if (cnt >= (unsigned int)args->appl.number) {
- garceful_stop_ping();
- break;
- }
- }
- cur = odp_time_local();
- if (odp_time_cmp(next, cur) > 0) {
- left = odp_time_diff(next, cur);
- stall = odp_time_to_ns(left);
- if (stall / ODP_TIME_SEC_IN_NS)
- sleep(1);
- else
- usleep(stall / ODP_TIME_USEC_IN_NS);
- continue;
- }
- next = odp_time_sum(cur, wait);
-
- switch (args->appl.mode) {
- case APPL_MODE_RCV:
- pkts_rcv = COUNTER_SUM(pkt_rcv, num_workers);
- pkts_snd = 0;
- pkts_snd_drop = 0;
- break;
- case APPL_MODE_PING:
- pkts_snd = COUNTER_SUM(pkt_snd, num_workers);
- pkts_snd_drop = COUNTER_SUM(pkt_snd_drop, num_workers);
- pkts_rcv = COUNTER_SUM(icmp_reply_rcv, num_workers);
- break;
- case APPL_MODE_UDP:
- pkts_snd = COUNTER_SUM(pkt_snd, num_workers);
- pkts_snd_drop = COUNTER_SUM(pkt_snd_drop, num_workers);
- break;
- default:
- continue;
- }
-
- pps_snd = (pkts_snd - pkts_snd_prev) / verbose_interval;
- pkts_snd_prev = pkts_snd;
- if (pps_snd > maximum_pps_snd)
- maximum_pps_snd = pps_snd;
-
- pps_rcv = (pkts_rcv - pkts_rcv_prev) / verbose_interval;
- pkts_rcv_prev = pkts_rcv;
- if (pps_rcv > maximum_pps_rcv)
- maximum_pps_rcv = pps_rcv;
-
- printf("sent: %" PRIu64 ", drops: %" PRIu64 ", "
- "send rate: %" PRIu64 " pps, "
- "max send rate: %" PRIu64 " pps, "
- "rcv: %" PRIu64 ", "
- "recv rate: %" PRIu64 " pps, "
- "max recv rate: %" PRIu64 " pps\n",
- pkts_snd, pkts_snd_drop,
- pps_snd, maximum_pps_snd,
- pkts_rcv, pps_rcv, maximum_pps_rcv);
- fflush(NULL);
- }
-
- for (i = 0; i < num_workers; i++)
- args->thread[i].stop = 1;
-}
-
-/**
- * ODP packet example main function
- */
-int main(int argc, char *argv[])
-{
- odph_helper_options_t helper_options;
- odph_thread_t thread_tbl[MAX_WORKERS];
- odp_pool_t pool;
- int num_workers;
- uint32_t num_rx_queues, num_tx_queues;
- int i;
- odp_shm_t shm;
- odp_cpumask_t cpumask;
- char cpumaskstr[ODP_CPUMASK_STR_SIZE];
- odp_pool_param_t params;
- interface_t *ifs;
- odp_instance_t instance;
- odp_init_t init_param;
- odph_thread_common_param_t thr_common;
- odph_thread_param_t thr_param;
-
- /* Signal handler has to be registered before global init in case ODP
- * implementation creates internal threads/processes. */
- signal(SIGINT, sig_handler);
-
- /* 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_param_init(&init_param);
- init_param.mem_model = helper_options.mem_model;
-
- /* Init ODP before calling anything else */
- if (odp_init_global(&instance, &init_param, NULL)) {
- ODPH_ERR("Error: ODP global init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
- ODPH_ERR("Error: ODP local init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- /* Reserve memory for args from shared mem */
- shm = odp_shm_reserve("shm_args", sizeof(args_t),
- ODP_CACHE_LINE_SIZE, 0);
-
- if (shm == ODP_SHM_INVALID) {
- ODPH_ERR("Error: shared mem reserve failed.\n");
- exit(EXIT_FAILURE);
- }
-
- args = odp_shm_addr(shm);
-
- if (args == NULL) {
- ODPH_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 = 1;
- num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
-
- if (args->appl.num_workers) {
- /* -w option: number of workers */
- num_workers = args->appl.num_workers;
- num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
- } else if (args->appl.mask) {
- /* -c option: cpumask */
- odp_cpumask_from_str(&cpumask, args->appl.mask);
- num_workers = odp_cpumask_count(&cpumask);
- }
-
- (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
-
- printf("num worker threads: %i\n", num_workers);
- printf("first CPU: %i\n", odp_cpumask_first(&cpumask));
- printf("cpu mask: %s\n", cpumaskstr);
- fflush(NULL);
-
- /* ping mode need two workers */
- if (args->appl.mode == APPL_MODE_PING) {
- if (num_workers < 2) {
- ODPH_ERR("Need at least two worker threads\n");
- exit(EXIT_FAILURE);
- } else {
- num_workers = 2;
- }
- }
- args->thread_cnt = num_workers;
-
- /* Burst size */
- if (args->appl.mode == APPL_MODE_PING) {
- args->tx_burst_size = 1;
- args->rx_burst_size = 1;
- } else if (args->appl.mode == APPL_MODE_UDP) {
- args->tx_burst_size = args->appl.udp_tx_burst;
- args->rx_burst_size = 0;
- } else {
- args->tx_burst_size = 0;
- args->rx_burst_size = args->appl.rx_burst;
- }
-
- /* Configure scheduler */
- odp_schedule_config(NULL);
-
- /* Create packet pool */
- odp_pool_param_init(&params);
- params.pkt.seg_len = POOL_PKT_LEN;
- params.pkt.len = POOL_PKT_LEN;
- params.pkt.num = POOL_NUM_PKT;
- params.type = ODP_POOL_PACKET;
-
- pool = odp_pool_create("packet_pool", &params);
-
- if (pool == ODP_POOL_INVALID) {
- ODPH_ERR("Error: packet pool create failed.\n");
- exit(EXIT_FAILURE);
- }
- odp_pool_print(pool);
-
- ifs = malloc(sizeof(interface_t) * args->appl.if_count);
-
- for (i = 0; i < args->appl.if_count; ++i) {
- if (args->appl.mode == APPL_MODE_PING) {
- num_rx_queues = 1;
- num_tx_queues = 1;
- } else if (args->appl.mode == APPL_MODE_UDP) {
- num_rx_queues = 0;
- num_tx_queues = num_workers / args->appl.if_count;
- if (i < num_workers % args->appl.if_count)
- num_tx_queues++;
- } else { /* APPL_MODE_RCV*/
- num_rx_queues = num_workers / args->appl.if_count;
- if (i < num_workers % args->appl.if_count)
- num_rx_queues++;
- num_tx_queues = 0;
- }
-
- if (create_pktio(args->appl.if_names[i], pool, num_rx_queues,
- num_tx_queues, &ifs[i])) {
- ODPH_ERR("Error: create interface %s failed.\n",
- args->appl.if_names[i]);
- exit(EXIT_FAILURE);
- }
- }
-
- /* Create and init worker threads */
- memset(thread_tbl, 0, sizeof(thread_tbl));
-
- /* Init threads params */
- odph_thread_param_init(&thr_param);
- thr_param.thr_type = ODP_THREAD_WORKER;
-
- odph_thread_common_param_init(&thr_common);
- thr_common.instance = instance;
-
- /* num workers + print thread */
- odp_barrier_init(&args->barrier, num_workers + 1);
-
- if (args->appl.mode == APPL_MODE_PING) {
- odp_cpumask_t cpu_mask;
- int cpu_first, cpu_next;
- thread_args_t *thr_args;
-
- odp_cpumask_zero(&cpu_mask);
- cpu_first = odp_cpumask_first(&cpumask);
- odp_cpumask_set(&cpu_mask, cpu_first);
-
- thr_args = &args->thread[PING_THR_RX];
- if (!args->appl.sched)
- thr_args->rx.pktin = ifs[0].pktin[0];
- thr_args->pool = pool;
- thr_args->mode = args->appl.mode;
-
- if (args->appl.sched)
- thr_param.start = gen_recv_thread;
- else
- thr_param.start = gen_recv_direct_thread;
-
- thr_param.arg = thr_args;
-
- thr_common.cpumask = &cpu_mask;
-
- odph_thread_create(&thread_tbl[PING_THR_RX], &thr_common,
- &thr_param, 1);
-
- thr_args = &args->thread[PING_THR_TX];
- thr_args->tx.pktout = ifs[0].pktout[0];
- thr_args->tx.pktout_cfg = &ifs[0].config.pktout;
- thr_args->pool = pool;
- thr_args->mode = args->appl.mode;
- cpu_next = odp_cpumask_next(&cpumask, cpu_first);
- odp_cpumask_zero(&cpu_mask);
- odp_cpumask_set(&cpu_mask, cpu_next);
-
- thr_param.start = gen_send_thread;
- thr_param.arg = thr_args;
-
- odph_thread_create(&thread_tbl[PING_THR_TX], &thr_common,
- &thr_param, 1);
-
- } else {
- int cpu = odp_cpumask_first(&cpumask);
- udp_args_t *udp_param = NULL;
- uint16_t sport_range = args->appl.srcport_end -
- args->appl.srcport + 1;
- uint16_t dport_range = args->appl.dstport_end -
- args->appl.dstport + 1;
- float sport_step = (float)(sport_range) / num_workers;
- float dport_step = (float)(dport_range) / num_workers;
- odp_bool_t multi_flow = false;
-
- if (sport_range > 1 || dport_range > 1)
- multi_flow = true;
-
- for (i = 0; i < num_workers; ++i) {
- odp_cpumask_t thd_mask;
- int (*thr_run_func)(void *);
- int if_idx, pktq_idx;
- uint64_t start_seq;
-
- if_idx = i % args->appl.if_count;
-
- if (args->appl.mode == APPL_MODE_RCV) {
- pktq_idx = (i / args->appl.if_count) %
- ifs[if_idx].pktin_count;
- if (!args->appl.sched)
- args->thread[i].rx.pktin =
- ifs[if_idx].pktin[pktq_idx];
- } else {
- udp_param = &args->thread[i].tx.udp_param;
-
- pktq_idx = (i / args->appl.if_count) %
- ifs[if_idx].pktout_count;
- start_seq = i * args->tx_burst_size;
-
- args->thread[i].tx.pktout =
- ifs[if_idx].pktout[pktq_idx];
- args->thread[i].tx.pktout_cfg =
- &ifs[if_idx].config.pktout;
-
- udp_param->multi_flow = multi_flow;
- udp_param->srcport_start = args->appl.srcport;
- udp_param->srcport_end = args->appl.srcport_end;
- udp_param->srcport_crt = args->appl.srcport;
- if (sport_range > 1)
- udp_param->srcport_crt +=
- (uint16_t)(i * sport_step);
-
- udp_param->dstport_start = args->appl.dstport;
- udp_param->dstport_end = args->appl.dstport_end;
- udp_param->dstport_crt = args->appl.dstport;
- if (dport_range > 1)
- udp_param->dstport_crt +=
- (uint16_t)(i * dport_step);
-
- args->thread[i].counters.ctr_seq = start_seq;
- }
- 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) {
- if (args->appl.sched)
- thr_run_func = gen_recv_thread;
- else
- thr_run_func = gen_recv_direct_thread;
- } else {
- ODPH_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_cpumask_zero(&thd_mask);
- odp_cpumask_set(&thd_mask, cpu);
-
- thr_param.start = thr_run_func;
- thr_param.arg = &args->thread[i];
-
- thr_common.cpumask = &thd_mask;
-
- odph_thread_create(&thread_tbl[i], &thr_common,
- &thr_param, 1);
- cpu = odp_cpumask_next(&cpumask, cpu);
- }
- }
-
- print_global_stats(num_workers);
-
- /* Master thread waits for other threads to exit */
- odph_thread_join(thread_tbl, num_workers);
-
- for (i = 0; i < args->appl.if_count; ++i)
- odp_pktio_stop(ifs[i].pktio);
-
- for (i = 0; i < args->appl.if_count; ++i)
- odp_pktio_close(ifs[i].pktio);
- free(ifs);
- free(args->appl.if_names);
- free(args->appl.if_str);
- args = NULL;
- odp_mb_full();
- if (0 != odp_pool_destroy(pool))
- fprintf(stderr, "unable to destroy pool \"pool\"\n");
- if (0 != odp_shm_free(shm))
- fprintf(stderr, "unable to free \"shm\"\n");
- odp_term_local();
- odp_term_global(instance);
- 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 *token;
- size_t len;
- odp_cpumask_t cpumask, cpumask_args, cpumask_and;
- int i, num_workers;
- static const struct option longopts[] = {
- {"interface", required_argument, NULL, 'I'},
- {"workers", required_argument, NULL, 'w'},
- {"cpumask", required_argument, NULL, 'c'},
- {"srcmac", required_argument, NULL, 'a'},
- {"dstmac", required_argument, NULL, 'b'},
- {"srcip", required_argument, NULL, 's'},
- {"dstip", required_argument, NULL, 'd'},
- {"srcport", required_argument, NULL, 'e'},
- {"srcport_end", required_argument, NULL, 'j'},
- {"dstport", required_argument, NULL, 'f'},
- {"dstport_end", required_argument, NULL, 'k'},
- {"packetsize", required_argument, NULL, 'p'},
- {"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'},
- {"udp_tx_burst", required_argument, NULL, 'x'},
- {"rx_burst", required_argument, NULL, 'r'},
- {"csum", no_argument, NULL, 'y'},
- {"sched", no_argument, NULL, 'z'},
- {NULL, 0, NULL, 0}
- };
-
- static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:j:f:k"
- ":yr:z";
-
- appl_args->mode = -1; /* Invalid, must be changed by parsing */
- appl_args->number = -1;
- appl_args->payload = 56;
- appl_args->timeout = -1;
- appl_args->interval = DEFAULT_PKT_INTERVAL;
- appl_args->udp_tx_burst = DEFAULT_UDP_TX_BURST;
- appl_args->rx_burst = DEFAULT_RX_BURST;
- appl_args->srcport = 0;
- appl_args->srcport_end = 0;
- appl_args->dstport = 0;
- appl_args->dstport_end = 0;
- appl_args->csum = 0;
- appl_args->sched = 0;
- appl_args->num_workers = -1;
-
- while (1) {
- opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
- if (opt == -1)
- break; /* No more options */
-
- switch (opt) {
- case 'w':
- appl_args->num_workers = atoi(optarg);
- break;
- case 'c':
- appl_args->mask = optarg;
- odp_cpumask_from_str(&cpumask_args, args->appl.mask);
- num_workers = odp_cpumask_default_worker(&cpumask, 0);
- odp_cpumask_and(&cpumask_and, &cpumask_args, &cpumask);
- if (odp_cpumask_count(&cpumask_and) <
- odp_cpumask_count(&cpumask_args) ||
- odp_cpumask_count(&cpumask_args) > MAX_WORKERS) {
- ODPH_ERR("Wrong cpu mask, max cpu's:%d\n",
- num_workers < MAX_WORKERS ?
- num_workers : MAX_WORKERS);
- exit(EXIT_FAILURE);
- }
- 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' */
-
- appl_args->if_str = malloc(len);
- if (appl_args->if_str == NULL) {
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
-
- /* count the number of tokens separated by ',' */
- strcpy(appl_args->if_str, optarg);
- for (token = strtok(appl_args->if_str, ","), i = 0;
- token != NULL;
- token = strtok(NULL, ","), i++)
- ;
-
- 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(appl_args->if_str, optarg);
- for (token = strtok(appl_args->if_str, ","), i = 0;
- token != NULL; token = strtok(NULL, ","), i++) {
- 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 {
- ODPH_ERR("wrong mode!\n");
- exit(EXIT_FAILURE);
- }
- break;
-
- case 'a':
- if (odph_eth_addr_parse(&appl_args->srcmac, optarg)) {
- ODPH_ERR("wrong src mac:%s\n", optarg);
- exit(EXIT_FAILURE);
- }
- break;
-
- case 'b':
- if (odph_eth_addr_parse(&appl_args->dstmac, optarg)) {
- ODPH_ERR("wrong dst mac:%s\n", optarg);
- exit(EXIT_FAILURE);
- }
- break;
-
- case 's':
- if (scan_ip(optarg, &appl_args->srcip) != 1) {
- ODPH_ERR("wrong src ip:%s\n", optarg);
- exit(EXIT_FAILURE);
- }
- break;
-
- case 'd':
- if (scan_ip(optarg, &appl_args->dstip) != 1) {
- ODPH_ERR("wrong dst ip:%s\n", optarg);
- exit(EXIT_FAILURE);
- }
- break;
-
- case 'e':
- appl_args->srcport = (unsigned short)atoi(optarg);
- break;
- case 'j':
- appl_args->srcport_end = (unsigned short)atoi(optarg);
- break;
- case 'f':
- appl_args->dstport = (unsigned short)atoi(optarg);
- break;
- case 'k':
- appl_args->dstport_end = (unsigned short)atoi(optarg);
- break;
- case 'p':
- 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) {
- ODPH_ERR("should be root user\n");
- exit(EXIT_FAILURE);
- }
- break;
- case 'x':
- appl_args->udp_tx_burst = atoi(optarg);
- if (appl_args->udp_tx_burst > MAX_UDP_TX_BURST) {
- ODPH_ERR("wrong UDP Tx burst size (max %d)\n",
- MAX_UDP_TX_BURST);
- exit(EXIT_FAILURE);
- }
- break;
- case 'r':
- appl_args->rx_burst = atoi(optarg);
- if (appl_args->rx_burst > MAX_RX_BURST) {
- ODPH_ERR("wrong Rx burst size (max %d)\n",
- MAX_RX_BURST);
- exit(EXIT_FAILURE);
- }
- break;
-
- case 'y':
- appl_args->csum = 1;
- break;
- case 'z':
- appl_args->sched = 1;
- break;
- case 'h':
- usage(argv[0]);
- exit(EXIT_SUCCESS);
- break;
-
- default:
- break;
- }
- }
-
- if (appl_args->num_workers < 0)
- appl_args->num_workers = 0;
- else if (appl_args->num_workers == 0 ||
- appl_args->num_workers > MAX_WORKERS)
- appl_args->num_workers = MAX_WORKERS;
-
- if (appl_args->if_count == 0 || appl_args->mode == -1) {
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
-
- if ((appl_args->srcport != 0 && appl_args->srcport_end == 0) ||
- (appl_args->srcport_end < appl_args->srcport))
- appl_args->srcport_end = appl_args->srcport;
-
- if ((appl_args->dstport != 0 && appl_args->dstport_end == 0) ||
- (appl_args->dstport_end < appl_args->dstport))
- appl_args->dstport_end = appl_args->dstport;
-
- 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;
-
- odp_sys_info_print();
-
- 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(APPL_MODE_UDP);
- else if (appl_args->mode == 1)
- PRINT_APPL_MODE(APPL_MODE_PING);
- else
- PRINT_APPL_MODE(APPL_MODE_RCV);
- printf("\n\n");
- fflush(NULL);
-}
-
-/**
- * Print 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 ipv4 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 ipv4 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 --cpumask 0xc -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"
- " -s, --srcip src ip address\n"
- " -d, --dstip dst ip address\n"
- " -m, --mode work mode: send udp(u), receive(r), send icmp(p)\n"
- "\n"
- "Optional OPTIONS\n"
- " -h, --help Display help and exit.\n"
- " -e, --srcport udp source port start value\n"
- " default is 0\n"
- " -j, --srcport_end udp source port end value\n"
- " default is udp source port start value\n"
- " -f, --dstport udp destination port start value\n"
- " default is 0\n"
- " -k, --dstport_end udp destination port end value\n"
- " default is udp destination port start value\n"
- " -p, --packetsize payload length of the packets\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"
- " -w, --workers specify number of workers need to be assigned to application\n"
- " default is 1, 0 for all available\n"
- " -n, --count the number of packets to be send\n"
- " -c, --cpumask to set on cores\n"
- " -x, --udp_tx_burst size of UDP TX burst\n"
- " -r, --rx_burst size of RX burst\n"
- " -y, --csum use platform checksum support if available\n"
- " default is disabled\n"
- " -z, --sched use scheduler API to receive packets\n"
- " default is direct mode API\n"
- "\n", NO_PATH(progname), NO_PATH(progname)
- );
-}
diff --git a/example/ipfragreass/odp_ipfragreass_reassemble.c b/example/ipfragreass/odp_ipfragreass_reassemble.c
index 55ee42504..89055e6e4 100644
--- a/example/ipfragreass/odp_ipfragreass_reassemble.c
+++ b/example/ipfragreass/odp_ipfragreass_reassemble.c
@@ -89,7 +89,7 @@ static inline uint32_t hash(odph_ipv4hdr_t *hdr)
{
uint32_t a = hdr->src_addr;
uint32_t b = hdr->dst_addr;
- uint32_t c = hdr->id << 16 | hdr->proto;
+ uint32_t c = (uint32_t)hdr->id << 16 | hdr->proto;
/* A degenerate 3x32-bit Jenkins hash */
c ^= b;
diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c
index a67a3a1e8..b6cc9ee22 100644
--- a/example/ipsec_api/odp_ipsec.c
+++ b/example/ipsec_api/odp_ipsec.c
@@ -45,6 +45,7 @@
#include <odp_ipsec_stream.h>
#else
static void init_stream_db(void) {}
+static void deinit_stream_db(void) {}
static void resolve_stream_db(void) {}
static int create_stream_db_inputs(void)
{
@@ -1154,9 +1155,9 @@ main(int argc, char *argv[])
shm = odp_shm_lookup("shm_sp_db");
if (odp_shm_free(shm) != 0)
ODPH_ERR("Error: shm free shm_sp_db failed\n");
- shm = odp_shm_lookup("stream_db");
- if (odp_shm_free(shm) != 0)
- ODPH_ERR("Error: shm free stream_db failed\n");
+
+ deinit_stream_db();
+
if (odp_shm_free(global->shm)) {
ODPH_ERR("Error: shm free global data failed\n");
exit(EXIT_FAILURE);
diff --git a/example/ipsec_crypto/odp_ipsec.c b/example/ipsec_crypto/odp_ipsec.c
index 92e32d301..490d2ad0a 100644
--- a/example/ipsec_crypto/odp_ipsec.c
+++ b/example/ipsec_crypto/odp_ipsec.c
@@ -46,6 +46,7 @@
#include <odp_ipsec_stream.h>
#else
static void init_stream_db(void) {}
+static void deinit_stream_db(void) {}
static void resolve_stream_db(void) {}
static int create_stream_db_inputs(void)
{
@@ -1437,9 +1438,9 @@ main(int argc, char *argv[])
shm = odp_shm_lookup("shm_sp_db");
if (odp_shm_free(shm) != 0)
ODPH_ERR("Error: shm free shm_sp_db failed\n");
- shm = odp_shm_lookup("stream_db");
- if (odp_shm_free(shm) != 0)
- ODPH_ERR("Error: shm free stream_db failed\n");
+
+ deinit_stream_db();
+
if (odp_shm_free(global->shm)) {
ODPH_ERR("Error: shm free global data failed\n");
exit(EXIT_FAILURE);
diff --git a/example/ipsec_crypto/odp_ipsec_fwd_db.c b/example/ipsec_crypto/odp_ipsec_fwd_db.c
index 292d9c7c6..482813d41 100644
--- a/example/ipsec_crypto/odp_ipsec_fwd_db.c
+++ b/example/ipsec_crypto/odp_ipsec_fwd_db.c
@@ -78,8 +78,7 @@ int create_fwd_db_entry(char *input, char **if_names, int if_count)
&entry->subnet.mask);
break;
case 1:
- strncpy(entry->oif, token, OIF_LEN - 1);
- entry->oif[OIF_LEN - 1] = 0;
+ odph_strcpy(entry->oif, token, OIF_LEN);
for (i = 0; i < if_count; i++) {
if (!strcmp(if_names[i], entry->oif)) {
match = 1;
diff --git a/example/ipsec_crypto/odp_ipsec_misc.h b/example/ipsec_crypto/odp_ipsec_misc.h
index 921c4e3c0..5fba274d0 100644
--- a/example/ipsec_crypto/odp_ipsec_misc.h
+++ b/example/ipsec_crypto/odp_ipsec_misc.h
@@ -167,18 +167,18 @@ char *ipv4_addr_str(char *b, uint32_t addr)
static inline
int parse_ipv4_string(char *ipaddress, uint32_t *addr, uint32_t *mask)
{
- int b[4];
+ unsigned int b[4];
int qualifier = 32;
int converted;
if (strchr(ipaddress, '/')) {
- converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
+ converted = sscanf(ipaddress, "%u.%u.%u.%u/%d",
&b[3], &b[2], &b[1], &b[0],
&qualifier);
if (5 != converted)
return -1;
} else {
- converted = sscanf(ipaddress, "%d.%d.%d.%d",
+ converted = sscanf(ipaddress, "%u.%u.%u.%u",
&b[3], &b[2], &b[1], &b[0]);
if (4 != converted)
return -1;
@@ -189,7 +189,7 @@ int parse_ipv4_string(char *ipaddress, uint32_t *addr, uint32_t *mask)
if (!qualifier || (qualifier > 32))
return -1;
- *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
+ *addr = (uint32_t)b[0] | (uint32_t)b[1] << 8 | (uint32_t)b[2] << 16 | (uint32_t)b[3] << 24;
if (mask)
*mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
diff --git a/example/ipsec_crypto/odp_ipsec_stream.c b/example/ipsec_crypto/odp_ipsec_stream.c
index 330b4cc54..505ee900b 100644
--- a/example/ipsec_crypto/odp_ipsec_stream.c
+++ b/example/ipsec_crypto/odp_ipsec_stream.c
@@ -40,13 +40,14 @@ typedef struct ODP_PACKED stream_pkt_hdr_s {
uint8_t data[]; /**< Incrementing data stream */
} stream_pkt_hdr_t;
+static const char *shm_name = "stream_db";
stream_db_t *stream_db;
void init_stream_db(void)
{
odp_shm_t shm;
- shm = odp_shm_reserve("stream_db",
+ shm = odp_shm_reserve(shm_name,
sizeof(stream_db_t),
ODP_CACHE_LINE_SIZE,
0);
@@ -65,6 +66,28 @@ void init_stream_db(void)
memset(stream_db, 0, sizeof(*stream_db));
}
+void deinit_stream_db(void)
+{
+ stream_db_entry_t *stream = NULL;
+
+ for (stream = stream_db->list; NULL != stream; stream = stream->next) {
+ free(stream->input.intf);
+ free(stream->output.intf);
+ }
+
+ odp_shm_t shm = odp_shm_lookup(shm_name);
+
+ if (shm == ODP_SHM_INVALID) {
+ ODPH_ERR("Error: shared mem not found.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_shm_free(shm)) {
+ ODPH_ERR("Error: shared mem free failed.\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
int create_stream_db_entry(char *input)
{
int pos = 0;
diff --git a/example/ipsec_crypto/odp_ipsec_stream.h b/example/ipsec_crypto/odp_ipsec_stream.h
index 8e1e936dd..c6bbb618b 100644
--- a/example/ipsec_crypto/odp_ipsec_stream.h
+++ b/example/ipsec_crypto/odp_ipsec_stream.h
@@ -31,14 +31,14 @@ typedef struct stream_db_entry_s {
uint32_t verified; /**< Number successfully verified */
const EVP_MD *evp_md; /**< Digest method */
struct {
- const char *intf; /**< Input interface name */
+ char *intf; /**< Input interface name */
odp_pktio_t pktio; /**< Input PktI/O interface */
uint32_t ah_seq; /**< AH sequence number if present */
uint32_t esp_seq; /**< ESP sequence number if present */
ipsec_cache_entry_t *entry; /**< IPsec to apply on input */
} input;
struct {
- const char *intf; /**< Output interface name */
+ char *intf; /**< Output interface name */
odp_pktio_t pktio; /**< Output PktI/O interface */
ipsec_cache_entry_t *entry; /**t IPsec to verify on output */
} output;
@@ -58,6 +58,9 @@ extern stream_db_t *stream_db;
/** Initialize stream database global control structure */
void init_stream_db(void);
+/** Deinitialize stream database global control structure */
+void deinit_stream_db(void);
+
/**
* Create an stream DB entry
*
diff --git a/example/l2fwd/README b/example/l2fwd/README
deleted file mode 100644
index 091d046ea..000000000
--- a/example/l2fwd/README
+++ /dev/null
@@ -1,14 +0,0 @@
- ODP L2FWD application
-
-Source code and Makefiles placed under test/performance/ directory.
-
-This L2 forwarding application can be used as example reference as well
-as performance test for different odp modes (direct, queue or scheduler
-with parallel, atomic or ordered queues).
-
-Note that this example is tuned for performance. As a result, when using
-scheduled mode with direct packet I/O output or queued output with multiple
-output queues, packet order is not guaranteed. To achieve guaranteed order,
-use a single worker thread or output interfaces with single output
-queues. Other examples of scalable processing using ordered queues that
-preserve order can be seen in the odp_pktio_ordered performance test.
diff --git a/example/l2fwd/odp_l2fwd.c b/example/l2fwd/odp_l2fwd.c
deleted file mode 120000
index fb585f437..000000000
--- a/example/l2fwd/odp_l2fwd.c
+++ /dev/null
@@ -1 +0,0 @@
-../../test/performance/odp_l2fwd.c \ No newline at end of file
diff --git a/example/l2fwd_simple/odp_l2fwd_simple.c b/example/l2fwd_simple/odp_l2fwd_simple.c
index 5d9aaec87..1ea08cce1 100644
--- a/example/l2fwd_simple/odp_l2fwd_simple.c
+++ b/example/l2fwd_simple/odp_l2fwd_simple.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2016-2018 Linaro Limited
+ * Copyright (c) 2024 Nokia
*/
/**
@@ -101,12 +102,12 @@ static int run_worker(void *arg ODP_UNUSED)
if (odp_pktio_start(global->if0)) {
printf("unable to start input interface\n");
- exit(1);
+ return -1;
}
printf("started input interface\n");
if (odp_pktio_start(global->if1)) {
printf("unable to start output interface\n");
- exit(1);
+ return -1;
}
printf("started output interface\n");
printf("started all\n");
@@ -159,6 +160,7 @@ int main(int argc, char **argv)
odph_ethaddr_t correct_src;
uint32_t mtu1, mtu2;
odp_shm_t shm;
+ odph_thread_join_result_t res[MAX_WORKERS];
/* Let helper collect its own arguments (e.g. --odph_proc) */
argc = odph_parse_options(argc, argv);
@@ -271,11 +273,19 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
- if (odph_thread_join(thd, MAX_WORKERS) != MAX_WORKERS) {
+ if (odph_thread_join_result(thd, res, MAX_WORKERS) != MAX_WORKERS) {
printf("Error: failed to join threads\n");
exit(EXIT_FAILURE);
}
+ for (int i = 0; i < MAX_WORKERS; i++) {
+ if (res[i].is_sig || res[i].ret != 0) {
+ printf("Error: thread failure%s: %d\n", res[i].is_sig ?
+ " (signaled)" : "", res[i].ret);
+ exit(EXIT_FAILURE);
+ }
+ }
+
if (odp_pktio_stop(global->if0) || odp_pktio_close(global->if0)) {
printf("Error: failed to close interface %s\n", argv[1]);
exit(EXIT_FAILURE);
diff --git a/example/l3fwd/odp_l3fwd_db.c b/example/l3fwd/odp_l3fwd_db.c
index 7d82695be..622c0a118 100644
--- a/example/l3fwd/odp_l3fwd_db.c
+++ b/example/l3fwd/odp_l3fwd_db.c
@@ -401,8 +401,7 @@ int create_fwd_db_entry(char *input, char **oif, uint8_t **dst_mac)
&entry->subnet.depth);
break;
case 1:
- strncpy(entry->oif, token, OIF_LEN - 1);
- entry->oif[OIF_LEN - 1] = 0;
+ odph_strcpy(entry->oif, token, OIF_LEN);
*oif = entry->oif;
break;
case 2:
diff --git a/example/m4/configure.m4 b/example/m4/configure.m4
index b02fd72a5..b51d8bd42 100644
--- a/example/m4/configure.m4
+++ b/example/m4/configure.m4
@@ -22,7 +22,6 @@ 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
example/ipsec_api/Makefile
example/ipsec_crypto/Makefile
@@ -34,7 +33,6 @@ AC_CONFIG_FILES([example/classifier/Makefile
example/simple_pipeline/Makefile
example/switch/Makefile
example/sysinfo/Makefile
- example/time/Makefile
example/timer/Makefile
example/traffic_mgmt/Makefile
example/Makefile])
diff --git a/example/simple_pipeline/odp_simple_pipeline.c b/example/simple_pipeline/odp_simple_pipeline.c
index ad80bc394..3a05bf1c5 100644
--- a/example/simple_pipeline/odp_simple_pipeline.c
+++ b/example/simple_pipeline/odp_simple_pipeline.c
@@ -922,6 +922,9 @@ int main(int argc, char **argv)
odph_thread_join(thr_tbl, num_threads);
+ free(global->appl.if_names);
+ free(global->appl.if_str);
+
if (odp_pktio_close(global->if0)) {
printf("Error: failed to close interface %s\n", argv[1]);
exit(EXIT_FAILURE);
diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c
index df33f45cf..6ddbf0ad9 100644
--- a/example/sysinfo/odp_sysinfo.c
+++ b/example/sysinfo/odp_sysinfo.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2018 Linaro Limited
- * Copyright (c) 2022-2023 Nokia
+ * Copyright (c) 2022-2024 Nokia
*/
/**
@@ -169,6 +169,8 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher)
return "des";
case ODP_CIPHER_ALG_3DES_CBC:
return "3des_cbc";
+ case ODP_CIPHER_ALG_3DES_ECB:
+ return "3des_ecb";
case ODP_CIPHER_ALG_AES_CBC:
return "aes_cbc";
case ODP_CIPHER_ALG_AES_CTR:
@@ -193,6 +195,20 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher)
return "aes_eea2";
case ODP_CIPHER_ALG_ZUC_EEA3:
return "zuc_eea3";
+ case ODP_CIPHER_ALG_SNOW_V:
+ return "snow_v";
+ case ODP_CIPHER_ALG_SNOW_V_GCM:
+ return "snow_v_gcm";
+ case ODP_CIPHER_ALG_SM4_ECB:
+ return "sm4_ecb";
+ case ODP_CIPHER_ALG_SM4_CBC:
+ return "sm4_cbc";
+ case ODP_CIPHER_ALG_SM4_CTR:
+ return "sm4_ctr";
+ case ODP_CIPHER_ALG_SM4_GCM:
+ return "sm4_gcm";
+ case ODP_CIPHER_ALG_SM4_CCM:
+ return "sm4_ccm";
default:
return "Unknown";
}
@@ -215,6 +231,14 @@ static const char *auth_alg_name(odp_auth_alg_t auth)
return "sha384_hmac";
case ODP_AUTH_ALG_SHA512_HMAC:
return "sha512_hmac";
+ case ODP_AUTH_ALG_SHA3_224_HMAC:
+ return "sha3_224_hmac";
+ case ODP_AUTH_ALG_SHA3_256_HMAC:
+ return "sha3_256_hmac";
+ case ODP_AUTH_ALG_SHA3_384_HMAC:
+ return "sha3_384_hmac";
+ case ODP_AUTH_ALG_SHA3_512_HMAC:
+ return "sha3_512_hmac";
case ODP_AUTH_ALG_AES_GCM:
return "aes_gcm";
case ODP_AUTH_ALG_AES_GMAC:
@@ -235,6 +259,18 @@ static const char *auth_alg_name(odp_auth_alg_t auth)
return "aes_eia2";
case ODP_AUTH_ALG_ZUC_EIA3:
return "zuc_eia3";
+ case ODP_AUTH_ALG_SNOW_V_GCM:
+ return "snow_v_gcm";
+ case ODP_AUTH_ALG_SNOW_V_GMAC:
+ return "snow_v_gmac";
+ case ODP_AUTH_ALG_SM3_HMAC:
+ return "sm3_hmac";
+ case ODP_AUTH_ALG_SM4_GCM:
+ return "sm4_gcm";
+ case ODP_AUTH_ALG_SM4_GMAC:
+ return "sm4_gmac";
+ case ODP_AUTH_ALG_SM4_CCM:
+ return "sm4_ccm";
case ODP_AUTH_ALG_MD5:
return "md5";
case ODP_AUTH_ALG_SHA1:
@@ -247,6 +283,16 @@ static const char *auth_alg_name(odp_auth_alg_t auth)
return "sha384";
case ODP_AUTH_ALG_SHA512:
return "sha512";
+ case ODP_AUTH_ALG_SHA3_224:
+ return "sha3_224";
+ case ODP_AUTH_ALG_SHA3_256:
+ return "sha3_256";
+ case ODP_AUTH_ALG_SHA3_384:
+ return "sha3_384";
+ case ODP_AUTH_ALG_SHA3_512:
+ return "sha3_512";
+ case ODP_AUTH_ALG_SM3:
+ return "sm3";
default:
return "Unknown";
}
@@ -289,6 +335,20 @@ static void foreach_cipher(odp_crypto_cipher_algos_t ciphers, cipher_op_t op)
op(ODP_CIPHER_ALG_AES_EEA2);
if (ciphers.bit.zuc_eea3)
op(ODP_CIPHER_ALG_ZUC_EEA3);
+ if (ciphers.bit.snow_v)
+ op(ODP_CIPHER_ALG_SNOW_V);
+ if (ciphers.bit.snow_v_gcm)
+ op(ODP_CIPHER_ALG_SNOW_V_GCM);
+ if (ciphers.bit.sm4_ecb)
+ op(ODP_CIPHER_ALG_SM4_ECB);
+ if (ciphers.bit.sm4_cbc)
+ op(ODP_CIPHER_ALG_SM4_CBC);
+ if (ciphers.bit.sm4_ctr)
+ op(ODP_CIPHER_ALG_SM4_CTR);
+ if (ciphers.bit.sm4_gcm)
+ op(ODP_CIPHER_ALG_SM4_GCM);
+ if (ciphers.bit.sm4_ccm)
+ op(ODP_CIPHER_ALG_SM4_CCM);
}
static void foreach_auth(odp_crypto_auth_algos_t auths, auth_op_t op)
@@ -307,6 +367,14 @@ static void foreach_auth(odp_crypto_auth_algos_t auths, auth_op_t op)
op(ODP_AUTH_ALG_SHA384_HMAC);
if (auths.bit.sha512_hmac)
op(ODP_AUTH_ALG_SHA512_HMAC);
+ if (auths.bit.sha3_224_hmac)
+ op(ODP_AUTH_ALG_SHA3_224_HMAC);
+ if (auths.bit.sha3_256_hmac)
+ op(ODP_AUTH_ALG_SHA3_256_HMAC);
+ if (auths.bit.sha3_384_hmac)
+ op(ODP_AUTH_ALG_SHA3_384_HMAC);
+ if (auths.bit.sha3_512_hmac)
+ op(ODP_AUTH_ALG_SHA3_512_HMAC);
if (auths.bit.aes_gcm)
op(ODP_AUTH_ALG_AES_GCM);
if (auths.bit.aes_gmac)
@@ -327,6 +395,18 @@ static void foreach_auth(odp_crypto_auth_algos_t auths, auth_op_t op)
op(ODP_AUTH_ALG_AES_EIA2);
if (auths.bit.zuc_eia3)
op(ODP_AUTH_ALG_ZUC_EIA3);
+ if (auths.bit.snow_v_gcm)
+ op(ODP_AUTH_ALG_SNOW_V_GCM);
+ if (auths.bit.snow_v_gmac)
+ op(ODP_AUTH_ALG_SNOW_V_GMAC);
+ if (auths.bit.sm3_hmac)
+ op(ODP_AUTH_ALG_SM3_HMAC);
+ if (auths.bit.sm4_gcm)
+ op(ODP_AUTH_ALG_SM4_GCM);
+ if (auths.bit.sm4_gmac)
+ op(ODP_AUTH_ALG_SM4_GMAC);
+ if (auths.bit.sm4_ccm)
+ op(ODP_AUTH_ALG_SM4_CCM);
if (auths.bit.md5)
op(ODP_AUTH_ALG_MD5);
if (auths.bit.sha1)
@@ -339,6 +419,16 @@ static void foreach_auth(odp_crypto_auth_algos_t auths, auth_op_t op)
op(ODP_AUTH_ALG_SHA384);
if (auths.bit.sha512)
op(ODP_AUTH_ALG_SHA512);
+ if (auths.bit.sha3_224)
+ op(ODP_AUTH_ALG_SHA3_224);
+ if (auths.bit.sha3_256)
+ op(ODP_AUTH_ALG_SHA3_256);
+ if (auths.bit.sha3_384)
+ op(ODP_AUTH_ALG_SHA3_384);
+ if (auths.bit.sha3_512)
+ op(ODP_AUTH_ALG_SHA3_512);
+ if (auths.bit.sm3)
+ op(ODP_AUTH_ALG_SM3);
}
static void print_cipher_capa(odp_cipher_alg_t cipher)
@@ -686,7 +776,7 @@ static void parse_interfaces(appl_args_t *config, const char *optarg)
MAX_NAME_LEN);
exit(EXIT_FAILURE);
}
- strncpy(config->pktio[config->num_pktio].name, tmp, MAX_NAME_LEN);
+ odph_strcpy(config->pktio[config->num_pktio].name, tmp, MAX_NAME_LEN);
config->num_pktio++;
diff --git a/example/time/.gitignore b/example/time/.gitignore
deleted file mode 100644
index 938c1aaed..000000000
--- a/example/time/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-odp_time_global
diff --git a/example/time/Makefile.am b/example/time/Makefile.am
deleted file mode 100644
index b5a1ad35d..000000000
--- a/example/time/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-include $(top_srcdir)/example/Makefile.inc
-
-bin_PROGRAMS = odp_time_global
-
-if test_example
-TESTS = odp_time_global
-endif
-
-odp_time_global_SOURCES = odp_time_global_test.c
diff --git a/example/time/odp_time_global_test.c b/example/time/odp_time_global_test.c
deleted file mode 100644
index 7c1409abf..000000000
--- a/example/time/odp_time_global_test.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-/**
- * @example odp_time_global_test.c
- *
- * Time API test application
- *
- * @cond _ODP_HIDE_FROM_DOXYGEN_
- */
-
-#include <inttypes.h>
-
-#include <odp_api.h>
-#include <odp/helper/odph_api.h>
-
-#define MAX_WORKERS 32
-#define MAX_NUM_BUF 8192
-#define ITERATION_NUM 2048
-#define LOG_BASE 8
-#define LOG_ENTRY_SIZE 19
-#define LOG_LINE_SIZE (LOG_BASE * LOG_ENTRY_SIZE + 1)
-
-#define QUEUE_NAME_PREFIX "thread_queue_"
-
-typedef struct {
- odp_time_t timestamp;
- int id;
-} timestamp_event_t;
-
-typedef struct {
- uint8_t thr;
- uint8_t id;
- odp_time_t time;
-} log_entry_t;
-
-typedef struct {
- uint32_t iteration_num;
- odp_atomic_u32_t iteration_counter;
- odp_atomic_u32_t id_counter;
- odp_atomic_u32_t log_counter;
- odp_atomic_u32_t err_counter;
- odp_barrier_t start_barrier;
- odp_barrier_t end_barrier;
- int thread_num;
- log_entry_t *log;
- int log_enries_num;
-} test_globals_t;
-
-static void print_log(test_globals_t *gbls)
-{
- uint32_t err_num;
- int i, j, k, pad;
- char line[LOG_LINE_SIZE];
-
- memset(line, '-', LOG_LINE_SIZE - 1);
- line[LOG_LINE_SIZE - 1] = 0;
- for (i = 1; i <= gbls->thread_num; i++) {
- printf("\n==== history of %d buffer, time,ns (thread) ====\n%s\n",
- i, line);
-
- /* print log for buffer */
- k = 0;
- for (j = 0; j < gbls->log_enries_num; j++)
- if (gbls->log[j].id == i) {
- printf("%10" PRIu64 " (%-3d)",
- odp_time_to_ns(gbls->log[j].time),
- gbls->log[j].thr);
-
- if (!(++k % LOG_BASE))
- printf(" |\n");
- else
- printf(" =>");
- }
-
- if ((k % LOG_BASE)) {
- pad = (LOG_BASE - k % LOG_BASE) * LOG_ENTRY_SIZE - 4;
- printf(" end%*c\n%s\n", pad, '|', line);
- } else {
- printf("%s\n", line);
- }
- }
-
- printf("\n\n");
-
- err_num = odp_atomic_load_u32(&gbls->err_counter);
- if (err_num)
- printf("Number of errors: %u\n", err_num);
-}
-
-static void generate_next_queue(test_globals_t *gbls, odp_queue_t *queue,
- unsigned int id)
-{
- int thr;
- uint8_t rand_u8;
- char queue_name[sizeof(QUEUE_NAME_PREFIX) + 2];
- unsigned int rand_id = 1;
-
- thr = odp_thread_id();
-
- /* generate next random id */
- if (gbls->thread_num > 1) {
- do {
- odp_random_data(&rand_u8, 1, ODP_RANDOM_BASIC);
- rand_id = rand_u8 % gbls->thread_num + 1;
- } while (rand_id == id);
- }
-
- sprintf(queue_name, QUEUE_NAME_PREFIX "%d", rand_id);
- *queue = odp_queue_lookup(queue_name);
-
- if (ODP_QUEUE_INVALID == *queue)
- ODPH_ABORT("Cannot lookup thread queue \"%s\", thread %d\n",
- queue_name, thr);
-}
-
-static void test_global_timestamps(test_globals_t *gbls,
- odp_queue_t queue, unsigned int id)
-{
- int thr;
- int log_entry;
- odp_event_t ev;
- odp_time_t time;
- odp_buffer_t buf;
- odp_queue_t queue_next;
- timestamp_event_t *timestamp_ev;
-
- thr = odp_thread_id();
- while (odp_atomic_load_u32(&gbls->iteration_counter) <
- gbls->iteration_num) {
- ev = odp_queue_deq(queue);
-
- if (ev == ODP_EVENT_INVALID)
- continue;
-
- buf = odp_buffer_from_event(ev);
- timestamp_ev = (timestamp_event_t *)odp_buffer_addr(buf);
-
- time = odp_time_global();
- if (odp_time_cmp(time, timestamp_ev->timestamp) < 0) {
- ODPH_ERR("timestamp is less than previous time_prev=%"
- PRIu64 "ns, time_next=%"
- PRIu64 "ns, thread %d\n",
- odp_time_to_ns(timestamp_ev->timestamp),
- odp_time_to_ns(time), thr);
- odp_atomic_inc_u32(&gbls->err_counter);
- }
-
- /* update the log */
- log_entry = odp_atomic_fetch_inc_u32(&gbls->log_counter);
- gbls->log[log_entry].time = timestamp_ev->timestamp;
- gbls->log[log_entry].id = timestamp_ev->id;
- gbls->log[log_entry].thr = thr;
-
- /* assign new current time and send */
- generate_next_queue(gbls, &queue_next, id);
- timestamp_ev->timestamp = time;
- if (odp_queue_enq(queue_next, ev))
- ODPH_ABORT("Cannot enqueue event %" PRIu64 " on queue "
- "%" PRIu64 ", thread %d\n",
- odp_event_to_u64(ev),
- odp_queue_to_u64(queue_next), thr);
-
- odp_atomic_inc_u32(&gbls->iteration_counter);
- }
-}
-
-/**
- * @internal Worker thread
- *
- * @param ptr Pointer to test arguments
- *
- * @return Pointer to exit status
- */
-static int run_thread(void *ptr)
-{
- int thr;
- uint32_t id;
- odp_event_t ev;
- odp_buffer_t buf;
- test_globals_t *gbls;
- odp_pool_t buffer_pool;
- odp_queue_t queue, queue_next;
- timestamp_event_t *timestamp_ev;
- char queue_name[sizeof(QUEUE_NAME_PREFIX) + 2];
-
- gbls = ptr;
- thr = odp_thread_id();
- printf("Thread %i starts on cpu %i\n", thr, odp_cpu_id());
-
- /*
- * Allocate own queue for receiving timestamps.
- * Own queue is needed to guarantee that next thread for receiving
- * buffer is not the same thread.
- */
- id = odp_atomic_fetch_inc_u32(&gbls->id_counter);
- sprintf(queue_name, QUEUE_NAME_PREFIX "%d", id);
- queue = odp_queue_create(queue_name, NULL);
- if (queue == ODP_QUEUE_INVALID)
- ODPH_ABORT("Cannot create thread queue, thread %d", thr);
-
- /* allocate buffer for timestamp */
- buffer_pool = odp_pool_lookup("time buffers pool");
- if (buffer_pool == ODP_POOL_INVALID)
- ODPH_ABORT("Buffer pool was not found, thread %d\n", thr);
-
- buf = odp_buffer_alloc(buffer_pool);
- if (buf == ODP_BUFFER_INVALID)
- ODPH_ABORT("Buffer was not allocated, thread %d\n", thr);
-
- /* wait all threads allocated their queues */
- odp_barrier_wait(&gbls->start_barrier);
-
- /* enqueue global timestamp to some queue of some other thread */
- generate_next_queue(gbls, &queue_next, id);
-
- /* save global timestamp and id for tracing */
- ev = odp_buffer_to_event(buf);
- timestamp_ev = (timestamp_event_t *)odp_buffer_addr(buf);
- timestamp_ev->id = id;
- timestamp_ev->timestamp = odp_time_global();
- if (odp_queue_enq(queue_next, ev))
- ODPH_ABORT("Cannot enqueue timestamp event %" PRIu64 " on "
- "queue %" PRIu64 ", thread %d", odp_event_to_u64(ev),
- odp_queue_to_u64(queue_next), thr);
-
- test_global_timestamps(gbls, queue, id);
-
- /* wait all threads are finished their jobs */
- odp_barrier_wait(&gbls->end_barrier);
-
- /* free all events on the allocated queue */
- while (1) {
- ev = odp_queue_deq(queue);
- if (ev == ODP_EVENT_INVALID)
- break;
-
- buf = odp_buffer_from_event(ev);
- odp_buffer_free(buf);
- }
-
- /* free allocated queue */
- if (odp_queue_destroy(queue))
- ODPH_ABORT("Cannot destroy queue %" PRIu64 "",
- odp_queue_to_u64(queue));
-
- printf("Thread %i exits\n", thr);
- fflush(NULL);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int err = 0;
- odp_pool_t pool = ODP_POOL_INVALID;
- int num_workers;
- test_globals_t *gbls;
- odp_cpumask_t cpumask;
- odp_pool_capability_t pool_capa;
- odp_pool_param_t pool_param;
- odp_shm_t shm_glbls = ODP_SHM_INVALID;
- odp_shm_t shm_log = ODP_SHM_INVALID;
- int log_size, log_enries_num;
- odph_helper_options_t helper_options;
- odph_thread_t thread_tbl[MAX_WORKERS];
- odp_instance_t instance;
- odp_init_t init_param;
- odph_thread_common_param_t thr_common;
- odph_thread_param_t thr_param;
-
- printf("\nODP global time test starts\n");
-
- /* 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_param_init(&init_param);
- init_param.mem_model = helper_options.mem_model;
-
- if (odp_init_global(&instance, &init_param, NULL)) {
- err = 1;
- ODPH_ERR("ODP global init failed.\n");
- goto end;
- }
-
- /* Init this thread. */
- if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
- err = 1;
- ODPH_ERR("ODP local init failed.\n");
- goto err_global;
- }
-
- num_workers = MAX_WORKERS;
- num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
-
- shm_glbls = odp_shm_reserve("test_globals", sizeof(test_globals_t),
- ODP_CACHE_LINE_SIZE, 0);
- if (ODP_SHM_INVALID == shm_glbls) {
- err = 1;
- ODPH_ERR("Error: shared mem reserve failed.\n");
- goto err;
- }
-
- log_enries_num = num_workers * (ITERATION_NUM + num_workers);
- log_size = sizeof(log_entry_t) * log_enries_num;
- shm_log = odp_shm_reserve("test_log", log_size, ODP_CACHE_LINE_SIZE, 0);
- if (ODP_SHM_INVALID == shm_log) {
- err = 1;
- ODPH_ERR("Error: shared mem reserve failed.\n");
- goto err;
- }
-
- gbls = odp_shm_addr(shm_glbls);
- gbls->thread_num = num_workers;
- gbls->iteration_num = ITERATION_NUM;
- odp_atomic_store_u32(&gbls->iteration_counter, 0);
- odp_atomic_store_u32(&gbls->id_counter, 1);
- odp_atomic_store_u32(&gbls->log_counter, 0);
- odp_atomic_store_u32(&gbls->err_counter, 0);
- gbls->log_enries_num = log_enries_num;
- gbls->log = odp_shm_addr(shm_log);
- odp_barrier_init(&gbls->start_barrier, num_workers);
- odp_barrier_init(&gbls->end_barrier, num_workers);
- memset(gbls->log, 0, log_size);
-
- if (odp_pool_capability(&pool_capa)) {
- err = 1;
- ODPH_ERR("Error: pool capability failed.\n");
- goto err;
- }
-
- odp_pool_param_init(&pool_param);
-
- pool_param.buf.size = sizeof(timestamp_event_t);
- pool_param.buf.num = MAX_NUM_BUF;
- pool_param.type = ODP_POOL_BUFFER;
-
- if (pool_capa.buf.max_num && MAX_NUM_BUF > pool_capa.buf.max_num)
- pool_param.buf.num = pool_capa.buf.max_num;
-
- pool = odp_pool_create("time buffers pool", &pool_param);
- if (pool == ODP_POOL_INVALID) {
- err = 1;
- ODPH_ERR("Pool create failed.\n");
- goto err;
- }
-
- odph_thread_common_param_init(&thr_common);
- odph_thread_param_init(&thr_param);
-
- thr_param.start = run_thread;
- thr_param.arg = gbls;
- thr_param.thr_type = ODP_THREAD_WORKER;
-
- thr_common.instance = instance;
- thr_common.cpumask = &cpumask;
- thr_common.share_param = 1;
-
- /* Create and launch worker threads */
- odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
-
- /* Wait for worker threads to exit */
- odph_thread_join(thread_tbl, num_workers);
-
- print_log(gbls);
-
-err:
- if (pool != ODP_POOL_INVALID)
- if (odp_pool_destroy(pool))
- err = 1;
-
- if (shm_log != ODP_SHM_INVALID)
- if (odp_shm_free(shm_log))
- err = 1;
-
- if (shm_glbls != ODP_SHM_INVALID)
- if (odp_shm_free(shm_glbls))
- err = 1;
-
- if (odp_term_local())
- err = 1;
-err_global:
- if (odp_term_global(instance))
- err = 1;
-end:
- if (err) {
- ODPH_ERR("Err: ODP global time test failed\n\n");
- return -1;
- }
-
- printf("ODP global time test complete\n\n");
- return 0;
-}
diff --git a/example/timer/.gitignore b/example/timer/.gitignore
index 2b077829d..9502b573b 100644
--- a/example/timer/.gitignore
+++ b/example/timer/.gitignore
@@ -1,5 +1,3 @@
*.log
*.trs
-odp_timer_accuracy
-odp_timer_test
odp_timer_simple
diff --git a/example/timer/Makefile.am b/example/timer/Makefile.am
index 66cf0edfb..007a2842b 100644
--- a/example/timer/Makefile.am
+++ b/example/timer/Makefile.am
@@ -1,18 +1,9 @@
include $(top_srcdir)/example/Makefile.inc
-bin_PROGRAMS = odp_timer_accuracy \
- odp_timer_simple \
- odp_timer_test
-
-odp_timer_accuracy_SOURCES = odp_timer_accuracy.c
+bin_PROGRAMS = odp_timer_simple
odp_timer_simple_SOURCES = odp_timer_simple.c
-odp_timer_test_SOURCES = odp_timer_test.c
-
if test_example
-TESTS = odp_timer_accuracy_run.sh \
- odp_timer_simple
+TESTS = odp_timer_simple
endif
-
-EXTRA_DIST = odp_timer_accuracy_run.sh
diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c
deleted file mode 100644
index e5df1c24e..000000000
--- a/example/timer/odp_timer_accuracy.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2018 Linaro Limited
- * Copyright (c) 2019-2023 Nokia
- */
-
-/**
- * @example odp_timer_accuracy.c
- *
- * ODP timer accuracy test application
- *
- * @cond _ODP_HIDE_FROM_DOXYGEN_
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-#include <unistd.h>
-#include <getopt.h>
-
-#include <odp_api.h>
-#include <odp/helper/odph_api.h>
-
-#define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
-#define MAX_QUEUES 1024
-#define MAX_FILENAME 128
-
-enum mode_e {
- MODE_ONESHOT = 0,
- MODE_RESTART_ABS,
- MODE_RESTART_REL,
- MODE_PERIODIC,
-};
-
-typedef struct test_opt_t {
- int cpu_count;
- unsigned long long period_ns;
- long long res_ns;
- unsigned long long res_hz;
- unsigned long long offset_ns;
- unsigned long long max_tmo_ns;
- unsigned long long num;
- unsigned long long num_warmup;
- unsigned long long burst;
- unsigned long long burst_gap;
- odp_fract_u64_t freq;
- unsigned long long max_multiplier;
- unsigned long long multiplier;
- enum mode_e mode;
- int clk_src;
- odp_queue_type_t queue_type;
- int num_queue;
- int groups;
- int init;
- int output;
- int early_retry;
- uint64_t warmup_timers;
- uint64_t tot_timers;
- uint64_t alloc_timers;
- char filename[MAX_FILENAME + 1];
-} test_opt_t;
-
-typedef struct timer_ctx_t {
- odp_timer_t timer;
- odp_event_t event;
- uint64_t nsec;
- uint64_t count;
- uint64_t first_period;
- int tmo_tick;
- int64_t first_tmo_diff;
- int64_t nsec_final;
-
-} timer_ctx_t;
-
-typedef struct {
- uint64_t nsec_before_sum;
- uint64_t nsec_before_min;
- uint64_t nsec_before_min_idx;
- uint64_t nsec_before_max;
- uint64_t nsec_before_max_idx;
-
- uint64_t nsec_after_sum;
- uint64_t nsec_after_min;
- uint64_t nsec_after_min_idx;
- uint64_t nsec_after_max;
- uint64_t nsec_after_max_idx;
-
- uint64_t num_before;
- uint64_t num_exact;
- uint64_t num_after;
-
- uint64_t num_too_near;
-
-} test_stat_t;
-
-typedef struct test_log_t {
- uint64_t tmo_ns;
- int64_t diff_ns;
- int tid;
-
-} test_log_t;
-
-typedef struct test_global_t {
- test_opt_t opt;
-
- test_stat_t stat[MAX_WORKERS];
-
- odp_queue_t queue[MAX_QUEUES];
- odp_schedule_group_t group[MAX_WORKERS];
- odp_timer_pool_t timer_pool;
- odp_pool_t timeout_pool;
- timer_ctx_t *timer_ctx;
- double res_ns;
- uint64_t start_tick;
- uint64_t start_ns;
- uint64_t period_tick;
- double period_dbl;
- odp_fract_u64_t base_freq;
- test_log_t *log;
- FILE *file;
- odp_barrier_t barrier;
- odp_atomic_u64_t events;
- odp_atomic_u64_t last_events;
-
-} test_global_t;
-
-static void print_usage(void)
-{
- printf("\n"
- "Timer accuracy test application.\n"
- "\n"
- "OPTIONS:\n"
- " -c, --count <num> CPU count, 0=all available, default=1\n"
- " -p, --period <nsec> Timeout period in nsec. Not used in periodic mode. Default: 200 msec\n"
- " -r, --res_ns <nsec> Timeout resolution in nsec. Default value is 0. Special values:\n"
- " 0: Use period / 10 as the resolution\n"
- " -1: In periodic mode, use resolution from capabilities\n"
- " -R, --res_hz <hertz> Timeout resolution in hertz. Set resolution either with -r (nsec) or -R (hertz),\n"
- " and leave other to 0. Default: 0 (not used)\n"
- " -f, --first <nsec> First timer offset in nsec. Default: 0 for periodic mode, otherwise 300 msec\n"
- " -x, --max_tmo <nsec> Maximum timeout in nsec. Not used in periodic mode.\n"
- " When 0, max tmo is calculated from other options. Default: 0\n"
- " -n, --num <number> Number of timeout periods. Default: 50\n"
- " -w, --warmup <number> Number of warmup periods. Default: 0\n"
- " -b, --burst <number> Number of timers per a timeout period. Default: 1\n"
- " -g, --burst_gap <nsec> Gap (in nsec) between timers within a burst. Default: 0\n"
- " In periodic mode, first + burst * burst_gap must be less than period length.\n"
- " -m, --mode <number> Test mode select (default: 0):\n"
- " 0: One-shot. Start all timers at init phase.\n"
- " 1: One-shot. Each period, restart timers with absolute time.\n"
- " 2: One-shot. Each period, restart timers with relative time.\n"
- " 3: Periodic.\n"
- " -P, --periodic <freq_integer:freq_numer:freq_denom:max_multiplier>\n"
- " Periodic timer pool parameters. Default: 5:0:0:1 (5 Hz)\n"
- " -M, --multiplier Periodic timer multiplier. Default: 1\n"
- " -o, --output <file> Output file for measurement logs\n"
- " -e, --early_retry <num> When timer restart fails due to ODP_TIMER_TOO_NEAR, retry this many times\n"
- " with expiration time incremented by the period. Default: 0\n"
- " -s, --clk_src Clock source select (default 0):\n"
- " 0: ODP_CLOCK_DEFAULT\n"
- " 1: ODP_CLOCK_SRC_1, ...\n"
- " -t, --queue_type Queue sync type. Default is 0 (PARALLEL).\n"
- " 0: PARALLEL\n"
- " 1: ATOMIC\n"
- " 2: ORDERED\n"
- " -q, --num_queue Number of queues. Default is 1.\n"
- " -G, --sched_groups Use dedicated schedule group for each worker.\n"
- " -i, --init Set global init parameters. Default: init params not set.\n"
- " -h, --help Display help and exit.\n\n");
-}
-
-static int parse_options(int argc, char *argv[], test_opt_t *test_opt)
-{
- int opt, long_index;
- const struct option longopts[] = {
- {"count", required_argument, NULL, 'c'},
- {"period", required_argument, NULL, 'p'},
- {"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'},
- {"warmup", required_argument, NULL, 'w'},
- {"burst", required_argument, NULL, 'b'},
- {"burst_gap", required_argument, NULL, 'g'},
- {"mode", required_argument, NULL, 'm'},
- {"periodic", required_argument, NULL, 'P'},
- {"multiplier", required_argument, NULL, 'M'},
- {"output", required_argument, NULL, 'o'},
- {"early_retry", required_argument, NULL, 'e'},
- {"clk_src", required_argument, NULL, 's'},
- {"queue_type", required_argument, NULL, 't'},
- {"num_queue", required_argument, NULL, 'q'},
- {"sched_groups", no_argument, NULL, 'G'},
- {"init", no_argument, NULL, 'i'},
- {"help", no_argument, NULL, 'h'},
- {NULL, 0, NULL, 0}
- };
- const char *shortopts = "+c:p:r:R:f:x:n:w:b:g:m:P:M:o:e:s:t:q:Gih";
- int ret = 0;
-
- memset(test_opt, 0, sizeof(*test_opt));
-
- test_opt->cpu_count = 1;
- test_opt->period_ns = 200 * ODP_TIME_MSEC_IN_NS;
- test_opt->res_ns = 0;
- test_opt->res_hz = 0;
- test_opt->offset_ns = UINT64_MAX;
- test_opt->max_tmo_ns = 0;
- test_opt->num = 50;
- test_opt->num_warmup = 0;
- test_opt->burst = 1;
- test_opt->burst_gap = 0;
- test_opt->mode = MODE_ONESHOT;
- test_opt->freq.integer = ODP_TIME_SEC_IN_NS / test_opt->period_ns;
- test_opt->freq.numer = 0;
- test_opt->freq.denom = 0;
- test_opt->max_multiplier = 1;
- test_opt->multiplier = 1;
- test_opt->clk_src = ODP_CLOCK_DEFAULT;
- test_opt->queue_type = ODP_SCHED_SYNC_PARALLEL;
- test_opt->groups = 0;
- test_opt->num_queue = 1;
- test_opt->init = 0;
- test_opt->output = 0;
- test_opt->early_retry = 0;
-
- while (1) {
- opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
-
- if (opt == -1)
- break; /* No more options */
-
- switch (opt) {
- case 'c':
- test_opt->cpu_count = atoi(optarg);
- break;
- case 'p':
- test_opt->period_ns = strtoull(optarg, NULL, 0);
- break;
- case 'r':
- test_opt->res_ns = strtoll(optarg, NULL, 0);
- break;
- case 'R':
- test_opt->res_hz = strtoull(optarg, NULL, 0);
- break;
- case 'f':
- test_opt->offset_ns = strtoull(optarg, NULL, 0);
- break;
- case 'x':
- test_opt->max_tmo_ns = strtoull(optarg, NULL, 0);
- break;
- case 'n':
- test_opt->num = strtoull(optarg, NULL, 0);
- break;
- case 'w':
- test_opt->num_warmup = strtoull(optarg, NULL, 0);
- break;
- case 'b':
- test_opt->burst = strtoull(optarg, NULL, 0);
- break;
- case 'g':
- test_opt->burst_gap = strtoull(optarg, NULL, 0);
- break;
- case 'm':
- test_opt->mode = atoi(optarg);
- break;
- case 'P':
- sscanf(optarg, "%" SCNu64 ":%" SCNu64 ":%" SCNu64 ":%llu",
- &test_opt->freq.integer, &test_opt->freq.numer,
- &test_opt->freq.denom, &test_opt->max_multiplier);
- break;
- case 'M':
- test_opt->multiplier = strtoull(optarg, NULL, 0);
- break;
- case 'o':
- test_opt->output = 1;
- /* filename is NULL terminated in anycase */
- strncpy(test_opt->filename, optarg, MAX_FILENAME);
- break;
- case 'e':
- test_opt->early_retry = atoi(optarg);
- break;
- case 's':
- test_opt->clk_src = atoi(optarg);
- break;
- case 't':
- switch (atoi(optarg)) {
- case 1:
- test_opt->queue_type = ODP_SCHED_SYNC_ATOMIC;
- break;
- case 2:
- test_opt->queue_type = ODP_SCHED_SYNC_ORDERED;
- break;
- default:
- test_opt->queue_type = ODP_SCHED_SYNC_PARALLEL;
- break;
- }
- break;
- case 'q':
- test_opt->num_queue = atoi(optarg);
- break;
- case 'G':
- test_opt->groups = 1;
- break;
- case 'i':
- test_opt->init = 1;
- break;
- case 'h':
- print_usage();
- ret = -1;
- break;
- default:
- print_usage();
- ret = -1;
- break;
- }
- }
-
- if (test_opt->mode == MODE_PERIODIC) {
- if ((test_opt->freq.integer == 0 && test_opt->freq.numer == 0) ||
- (test_opt->freq.numer != 0 && test_opt->freq.denom == 0)) {
- printf("Bad frequency\n");
- return -1;
- }
-
- test_opt->period_ns =
- ODP_TIME_SEC_IN_NS / odp_fract_u64_to_dbl(&test_opt->freq);
-
- if (test_opt->offset_ns == UINT64_MAX)
- test_opt->offset_ns = 0;
- } else {
- if (test_opt->res_ns < 0) {
- printf("Resolution (res_ns) must be >= 0 with single shot timer\n");
- return -1;
- }
-
- if (test_opt->offset_ns == UINT64_MAX)
- test_opt->offset_ns = 300 * ODP_TIME_MSEC_IN_NS;
- }
-
- test_opt->warmup_timers = test_opt->num_warmup * test_opt->burst;
- test_opt->tot_timers =
- test_opt->warmup_timers + test_opt->num * test_opt->burst;
-
- if (test_opt->mode == MODE_ONESHOT)
- test_opt->alloc_timers = test_opt->tot_timers;
- else
- test_opt->alloc_timers = test_opt->burst;
-
- return ret;
-}
-
-static int single_shot_params(test_global_t *test_global, odp_timer_pool_param_t *timer_param,
- odp_timer_capability_t *timer_capa)
-{
- uint64_t res_ns, res_hz;
- uint64_t max_res_ns, max_res_hz;
- uint64_t period_ns = test_global->opt.period_ns;
- uint64_t num_tmo = test_global->opt.num + test_global->opt.num_warmup;
- uint64_t offset_ns = test_global->opt.offset_ns;
- enum mode_e mode = test_global->opt.mode;
-
- max_res_ns = timer_capa->max_res.res_ns;
- max_res_hz = timer_capa->max_res.res_hz;
-
- /* Default resolution */
- if (test_global->opt.res_ns == 0 && test_global->opt.res_hz == 0) {
- res_ns = test_global->opt.period_ns / 10;
- res_hz = 0;
- } else 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, 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;
- }
-
- if (res_ns)
- timer_param->res_ns = res_ns;
- else
- timer_param->res_hz = res_hz;
-
- if (mode == MODE_ONESHOT) {
- timer_param->min_tmo = offset_ns / 2;
- timer_param->max_tmo = offset_ns + ((num_tmo + 1) * period_ns);
- } else {
- timer_param->min_tmo = period_ns / 10;
- timer_param->max_tmo = offset_ns + (2 * period_ns);
- }
-
- if (test_global->opt.max_tmo_ns) {
- if (test_global->opt.max_tmo_ns < timer_param->max_tmo) {
- printf("Max tmo is too small. Must be at least %" PRIu64 " nsec.\n",
- timer_param->max_tmo);
- return -1;
- }
-
- timer_param->max_tmo = test_global->opt.max_tmo_ns;
- }
-
- printf(" period: %" PRIu64 " nsec\n", period_ns);
- printf(" max res nsec: %" PRIu64 "\n", max_res_ns);
- printf(" max res hertz: %" PRIu64 "\n", max_res_hz);
-
- test_global->period_dbl = period_ns;
-
- return 0;
-}
-
-static int periodic_params(test_global_t *test_global, odp_timer_pool_param_t *timer_param,
- odp_timer_capability_t *timer_capa)
-{
- int ret;
- uint64_t res_ns;
- odp_timer_periodic_capability_t capa;
- double freq_dbl, min_freq, max_freq;
- double opt_freq = odp_fract_u64_to_dbl(&test_global->opt.freq);
- odp_fract_u64_t freq = test_global->opt.freq;
- uint64_t res_hz = test_global->opt.res_hz;
- uint64_t max_multiplier = test_global->opt.max_multiplier;
- uint64_t multiplier = test_global->opt.multiplier;
-
- if (res_hz) {
- res_ns = ODP_TIME_SEC_IN_NS / res_hz;
- } else {
- res_ns = test_global->opt.res_ns;
-
- /* Default resolution */
- if (res_ns == 0)
- res_ns = ODP_TIME_SEC_IN_NS / (10 * multiplier * opt_freq);
- }
-
- if (res_ns == 0) {
- printf("Too high resolution\n");
- return -1;
- }
-
- /* Resolution from capa */
- if (test_global->opt.res_ns < 0)
- res_ns = 0;
-
- min_freq = odp_fract_u64_to_dbl(&timer_capa->periodic.min_base_freq_hz);
- max_freq = odp_fract_u64_to_dbl(&timer_capa->periodic.max_base_freq_hz);
-
- capa.base_freq_hz = freq;
- capa.max_multiplier = max_multiplier;
- capa.res_ns = res_ns;
-
- ret = odp_timer_periodic_capability(test_global->opt.clk_src, &capa);
-
- if (ret < 0) {
- printf("Requested periodic timer capabilities are not supported.\n"
- "Capabilities: min base freq %g Hz, max base freq %g Hz, "
- "max res %" PRIu64 " Hz\n", min_freq, max_freq, timer_capa->max_res.res_hz);
- return -1;
- }
-
- if (ret == 0) {
- printf("Requested base frequency is not met. Using %.2f Hz instead of %.2f Hz.\n",
- odp_fract_u64_to_dbl(&capa.base_freq_hz), opt_freq);
-
- freq = capa.base_freq_hz;
- }
-
- if (res_ns == 0)
- res_ns = capa.res_ns;
-
- freq_dbl = odp_fract_u64_to_dbl(&freq);
- test_global->base_freq = freq;
- test_global->period_dbl = ODP_TIME_SEC_IN_NS / (multiplier * freq_dbl);
-
- /* Min/max tmo are ignored, leave those to default values */
- timer_param->timer_type = ODP_TIMER_TYPE_PERIODIC;
- timer_param->periodic.base_freq_hz = freq;
- timer_param->periodic.max_multiplier = max_multiplier;
-
- if (res_hz)
- timer_param->res_hz = res_hz;
- else
- timer_param->res_ns = res_ns;
-
- printf(" min freq capa: %.2f hz\n", min_freq);
- printf(" max freq capa: %.2f hz\n", max_freq);
- printf(" freq option: %.2f hz\n", opt_freq);
- printf(" freq: %.2f hz\n", freq_dbl);
- printf(" freq integer: %" PRIu64 "\n", freq.integer);
- printf(" freq numer: %" PRIu64 "\n", freq.numer);
- printf(" freq denom: %" PRIu64 "\n", freq.denom);
- printf(" max_multiplier: %" PRIu64 "\n", max_multiplier);
- printf(" multiplier: %" PRIu64 "\n", multiplier);
- printf(" timer freq: %.2f hz\n", multiplier * freq_dbl);
- printf(" timer period: %.2f nsec\n", test_global->period_dbl);
- printf(" resolution capa: %" PRIu64 " nsec\n", capa.res_ns);
-
- return 0;
-}
-
-static int create_timers(test_global_t *test_global)
-{
- odp_pool_t pool;
- odp_pool_param_t pool_param;
- odp_timer_pool_t timer_pool;
- odp_timer_pool_param_t timer_param;
- odp_timer_capability_t timer_capa;
- odp_timer_t timer;
- odp_queue_t *queue;
- odp_schedule_group_t *group;
- odp_queue_param_t queue_param;
- uint64_t offset_ns;
- uint32_t max_timers;
- odp_event_t event;
- odp_timeout_t timeout;
- uint64_t i, num_tmo, num_warmup, burst, burst_gap;
- uint64_t tot_timers, alloc_timers;
- enum mode_e mode;
- odp_timer_clk_src_t clk_src;
- int ret;
-
- mode = test_global->opt.mode;
- alloc_timers = test_global->opt.alloc_timers;
- tot_timers = test_global->opt.tot_timers;
- num_warmup = test_global->opt.num_warmup;
- num_tmo = num_warmup + test_global->opt.num;
- burst = test_global->opt.burst;
- burst_gap = test_global->opt.burst_gap;
- offset_ns = test_global->opt.offset_ns;
- queue = test_global->queue;
- group = test_global->group;
-
- /* Always init globals for destroy calls */
- test_global->timer_pool = ODP_TIMER_POOL_INVALID;
- test_global->timeout_pool = ODP_POOL_INVALID;
-
- for (i = 0; i < alloc_timers; i++) {
- test_global->timer_ctx[i].timer = ODP_TIMER_INVALID;
- test_global->timer_ctx[i].event = ODP_EVENT_INVALID;
- }
-
- if (test_global->opt.groups) {
- /* Create groups */
-
- odp_thrmask_t zero;
-
- odp_thrmask_zero(&zero);
-
- for (i = 0; i < (uint64_t)test_global->opt.cpu_count; i++) {
- group[i] = odp_schedule_group_create(NULL, &zero);
-
- if (group[i] == ODP_SCHED_GROUP_INVALID) {
- printf("Group create failed.\n");
- return -1;
- }
- }
- }
-
- odp_queue_param_init(&queue_param);
- queue_param.type = ODP_QUEUE_TYPE_SCHED;
- queue_param.sched.prio = odp_schedule_default_prio();
- queue_param.sched.sync = test_global->opt.queue_type;
- queue_param.sched.group = ODP_SCHED_GROUP_ALL;
-
- for (i = 0; i < (uint64_t)test_global->opt.num_queue; i++) {
- if (test_global->opt.groups)
- queue_param.sched.group = group[i % test_global->opt.cpu_count];
-
- queue[i] = odp_queue_create(NULL, &queue_param);
- if (queue[i] == ODP_QUEUE_INVALID) {
- printf("Queue create failed.\n");
- return -1;
- }
- }
-
- odp_pool_param_init(&pool_param);
- pool_param.type = ODP_POOL_TIMEOUT;
- pool_param.tmo.num = alloc_timers;
-
- pool = odp_pool_create("timeout pool", &pool_param);
-
- if (pool == ODP_POOL_INVALID) {
- printf("Timeout pool create failed.\n");
- return -1;
- }
-
- test_global->timeout_pool = pool;
- clk_src = test_global->opt.clk_src;
-
- if (odp_timer_capability(clk_src, &timer_capa)) {
- printf("Timer capa failed\n");
- return -1;
- }
-
- max_timers = timer_capa.max_timers;
-
- if (mode == MODE_PERIODIC) {
- if (timer_capa.periodic.max_pools < 1) {
- printf("Error: Periodic timers not supported.\n");
- return -1;
- }
- max_timers = timer_capa.periodic.max_timers;
- }
-
- if (max_timers && test_global->opt.alloc_timers > max_timers) {
- printf("Error: Too many timers: %" PRIu64 ".\n"
- " Max timers: %u\n",
- test_global->opt.alloc_timers, max_timers);
- return -1;
- }
-
- printf("\nTest parameters:\n");
- printf(" clock source: %i\n", clk_src);
- printf(" max timers capa: %" PRIu32 "\n", max_timers);
- printf(" mode: %i\n", mode);
- printf(" queue type: %i\n", test_global->opt.queue_type);
- printf(" num queue: %i\n", test_global->opt.num_queue);
- printf(" sched groups: %s\n", test_global->opt.groups ? "yes" : "no");
-
- odp_timer_pool_param_init(&timer_param);
-
- if (mode == MODE_PERIODIC)
- ret = periodic_params(test_global, &timer_param, &timer_capa);
- else
- ret = single_shot_params(test_global, &timer_param, &timer_capa);
-
- if (ret)
- return ret;
-
- if (timer_param.res_hz) {
- test_global->res_ns = 1000000000.0 / timer_param.res_hz;
- printf(" resolution: %" PRIu64 " Hz\n", timer_param.res_hz);
- } else {
- test_global->res_ns = timer_param.res_ns;
- printf(" resolution: %" PRIu64 " nsec\n", timer_param.res_ns);
- }
-
- timer_param.num_timers = alloc_timers;
- timer_param.clk_src = clk_src;
-
- printf(" restart retries: %i\n", test_global->opt.early_retry);
- if (test_global->opt.output)
- printf(" log file: %s\n", test_global->opt.filename);
- printf(" start offset: %" PRIu64 " nsec\n", offset_ns);
- 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);
- printf(" num warmup: %" PRIu64 "\n", num_warmup);
- printf(" burst size: %" PRIu64 "\n", burst);
- printf(" burst gap: %" PRIu64 "\n", burst_gap);
- printf(" total timers: %" PRIu64 "\n", tot_timers);
- printf(" warmup timers: %" PRIu64 "\n", test_global->opt.warmup_timers);
- printf(" alloc timers: %" PRIu64 "\n", alloc_timers);
- printf(" warmup time: %.2f sec\n",
- (offset_ns + (num_warmup * test_global->period_dbl)) / 1000000000.0);
- printf(" test run time: %.2f sec\n\n",
- (offset_ns + (num_tmo * test_global->period_dbl)) / 1000000000.0);
-
- timer_pool = odp_timer_pool_create("timer_accuracy", &timer_param);
-
- if (timer_pool == ODP_TIMER_POOL_INVALID) {
- printf("Timer pool create failed\n");
- return -1;
- }
-
- if (odp_timer_pool_start_multi(&timer_pool, 1) != 1) {
- ODPH_ERR("Timer pool start failed\n");
- return -1;
- }
-
- odp_timer_pool_print(timer_pool);
-
- /* Spend some time so that current tick would not be zero */
- odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS);
-
- test_global->timer_pool = timer_pool;
-
- for (i = 0; i < alloc_timers; i++) {
- timer_ctx_t *ctx = &test_global->timer_ctx[i];
-
- timer = odp_timer_alloc(timer_pool, queue[i % test_global->opt.num_queue], ctx);
-
- if (timer == ODP_TIMER_INVALID) {
- printf("Timer alloc failed.\n");
- return -1;
- }
-
- ctx->timer = timer;
-
- timeout = odp_timeout_alloc(pool);
- if (timeout == ODP_TIMEOUT_INVALID) {
- printf("Timeout alloc failed\n");
- return -1;
- }
-
- ctx->event = odp_timeout_to_event(timeout);
- }
-
- /* Run scheduler few times to ensure that (software) timer is active */
- for (i = 0; i < 1000; i++) {
- event = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
-
- if (event != ODP_EVENT_INVALID) {
- printf("Spurious event received\n");
- odp_event_free(event);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int start_timers(test_global_t *test_global)
-{
- odp_timer_pool_t timer_pool;
- uint64_t start_tick;
- uint64_t period_ns, start_ns, nsec, offset_ns;
- odp_time_t time;
- uint64_t i, j, idx, num_tmo, num_warmup, burst, burst_gap;
- enum mode_e mode;
-
- mode = test_global->opt.mode;
- num_warmup = test_global->opt.num_warmup;
- num_tmo = num_warmup + test_global->opt.num;
- burst = test_global->opt.burst;
- burst_gap = test_global->opt.burst_gap;
- period_ns = test_global->opt.period_ns;
- offset_ns = test_global->opt.offset_ns;
- timer_pool = test_global->timer_pool;
- idx = 0;
-
- /* Record test start time and tick. Memory barriers forbid compiler and out-of-order
- * CPU to move samples apart. */
- odp_mb_full();
- start_tick = odp_timer_current_tick(timer_pool);
- time = odp_time_global();
- odp_mb_full();
-
- start_ns = odp_time_to_ns(time);
- test_global->start_tick = start_tick;
- test_global->start_ns = start_ns;
- test_global->period_tick = odp_timer_ns_to_tick(timer_pool, period_ns);
-
- /* When mode is not one-shot, set only one burst of timers initially */
- if (mode != MODE_ONESHOT)
- num_tmo = 1;
-
- for (i = 0; i < num_tmo; i++) {
- odp_timer_retval_t retval;
-
- for (j = 0; j < burst; j++) {
- timer_ctx_t *ctx = &test_global->timer_ctx[idx];
- odp_timer_start_t start_param;
-
- if (mode == MODE_PERIODIC) {
- odp_timer_periodic_start_t periodic_start;
-
- nsec = offset_ns + (j * burst_gap);
-
- /* By default, timer starts one period after current time. Round
- * floating point to closest integer number. */
- ctx->nsec = start_ns + test_global->period_dbl + 0.5;
- if (nsec)
- ctx->nsec = start_ns + nsec;
-
- ctx->count = 0;
- ctx->first_period = start_tick +
- odp_timer_ns_to_tick(timer_pool,
- test_global->period_dbl + 0.5);
- periodic_start.freq_multiplier = test_global->opt.multiplier;
- periodic_start.first_tick = 0;
- if (nsec)
- periodic_start.first_tick =
- start_tick + odp_timer_ns_to_tick(timer_pool, nsec);
- periodic_start.tmo_ev = ctx->event;
- retval = odp_timer_periodic_start(ctx->timer, &periodic_start);
- } else {
- nsec = offset_ns + (i * period_ns) + (j * burst_gap);
- ctx->nsec = start_ns + nsec;
- start_param.tick_type = ODP_TIMER_TICK_ABS;
- start_param.tick =
- start_tick + odp_timer_ns_to_tick(timer_pool, nsec);
- start_param.tmo_ev = ctx->event;
- retval = odp_timer_start(ctx->timer, &start_param);
- }
-
- if (retval != ODP_TIMER_SUCCESS) {
- printf("Timer[%" PRIu64 "] set failed: %i\n", idx, retval);
- return -1;
- }
-
- idx++;
- }
- }
-
- printf("\nStarting timers took %" PRIu64 " nsec\n", odp_time_global_ns() - start_ns);
-
- return 0;
-}
-
-static int destroy_timers(test_global_t *test_global)
-{
- uint64_t i, alloc_timers;
- odp_timer_t timer;
- int ret = 0;
-
- alloc_timers = test_global->opt.alloc_timers;
-
- for (i = 0; i < alloc_timers; i++) {
- timer = test_global->timer_ctx[i].timer;
-
- if (timer == ODP_TIMER_INVALID)
- break;
-
- if (odp_timer_free(timer)) {
- printf("Timer free failed: %" PRIu64 "\n", i);
- ret = -1;
- }
- }
-
- if (test_global->timer_pool != ODP_TIMER_POOL_INVALID)
- odp_timer_pool_destroy(test_global->timer_pool);
-
- if (test_global->timeout_pool != ODP_POOL_INVALID) {
- if (odp_pool_destroy(test_global->timeout_pool)) {
- printf("Pool destroy failed.\n");
- ret = -1;
- }
- }
-
- for (i = 0; i < (uint64_t)test_global->opt.num_queue; i++) {
- if (odp_queue_destroy(test_global->queue[i])) {
- printf("Queue destroy failed.\n");
- ret = -1;
- }
- }
-
- if (test_global->opt.groups) {
- for (i = 0; i < (uint64_t)test_global->opt.cpu_count; i++) {
- if (odp_schedule_group_destroy(test_global->group[i])) {
- printf("Group destroy failed.\n");
- ret = -1;
- }
- }
- }
-
- return ret;
-}
-
-static void print_nsec_error(const char *str, int64_t nsec, double res_ns,
- int tid, int idx)
-{
- printf(" %s: %12" PRIi64 " / %.3fx resolution",
- str, nsec, (double)nsec / res_ns);
- if (tid >= 0)
- printf(", thread %d", tid);
- if (idx >= 0)
- printf(", event %d", idx);
- printf("\n");
-}
-
-static void print_stat(test_global_t *test_global)
-{
- test_stat_t test_stat;
- test_stat_t *stat = &test_stat;
- uint64_t tot_timers;
- test_stat_t *s = test_global->stat;
- test_log_t *log = test_global->log;
- double res_ns = test_global->res_ns;
- uint64_t ave_after = 0;
- uint64_t ave_before = 0;
- uint64_t nsec_before_min_tid = 0;
- uint64_t nsec_before_max_tid = 0;
- uint64_t nsec_after_min_tid = 0;
- uint64_t nsec_after_max_tid = 0;
-
- memset(stat, 0, sizeof(*stat));
- stat->nsec_before_min = UINT64_MAX;
- stat->nsec_after_min = UINT64_MAX;
-
- for (int i = 1; i < test_global->opt.cpu_count + 1; i++) {
- stat->nsec_before_sum += s[i].nsec_before_sum;
- stat->nsec_after_sum += s[i].nsec_after_sum;
- stat->num_before += s[i].num_before;
- stat->num_exact += s[i].num_exact;
- stat->num_after += s[i].num_after;
- stat->num_too_near += s[i].num_too_near;
-
- if (s[i].nsec_before_min < stat->nsec_before_min) {
- stat->nsec_before_min = s[i].nsec_before_min;
- stat->nsec_before_min_idx = s[i].nsec_before_min_idx;
- nsec_before_min_tid = i;
- }
-
- if (s[i].nsec_after_min < stat->nsec_after_min) {
- stat->nsec_after_min = s[i].nsec_after_min;
- stat->nsec_after_min_idx = s[i].nsec_after_min_idx;
- nsec_after_min_tid = i;
- }
-
- if (s[i].nsec_before_max > stat->nsec_before_max) {
- stat->nsec_before_max = s[i].nsec_before_max;
- stat->nsec_before_max_idx = s[i].nsec_before_max_idx;
- nsec_before_max_tid = i;
- }
-
- if (s[i].nsec_after_max > stat->nsec_after_max) {
- stat->nsec_after_max = s[i].nsec_after_max;
- stat->nsec_after_max_idx = s[i].nsec_after_max_idx;
- nsec_after_max_tid = i;
- }
- }
-
- if (stat->num_after)
- ave_after = stat->nsec_after_sum / stat->num_after;
- else
- stat->nsec_after_min = 0;
-
- if (stat->num_before)
- ave_before = stat->nsec_before_sum / stat->num_before;
- else
- stat->nsec_before_min = 0;
-
- tot_timers = stat->num_before + stat->num_after + stat->num_exact;
-
- if (log) {
- FILE *file = test_global->file;
-
- fprintf(file, " Timer thread tmo(ns) diff(ns)\n");
-
- for (uint64_t i = 0; i < tot_timers; i++) {
- fprintf(file, "%8" PRIu64 " %7u %12" PRIu64 " %10"
- PRIi64 "\n", i, log[i].tid, log[i].tmo_ns, log[i].diff_ns);
- }
-
- fprintf(file, "\n");
- }
-
- printf("\nTest results:\n");
- printf(" num after: %12" PRIu64 " / %.2f%%\n",
- stat->num_after, 100.0 * stat->num_after / tot_timers);
- printf(" num before: %12" PRIu64 " / %.2f%%\n",
- stat->num_before, 100.0 * stat->num_before / tot_timers);
- printf(" num exact: %12" PRIu64 " / %.2f%%\n",
- stat->num_exact, 100.0 * stat->num_exact / tot_timers);
- printf(" num retry: %12" PRIu64 " / %.2f%%\n",
- stat->num_too_near, 100.0 * stat->num_too_near / tot_timers);
- printf(" error after (nsec):\n");
- print_nsec_error("min", stat->nsec_after_min, res_ns, nsec_after_min_tid,
- stat->nsec_after_min_idx);
- print_nsec_error("max", stat->nsec_after_max, res_ns, nsec_after_max_tid,
- stat->nsec_after_max_idx);
- print_nsec_error("ave", ave_after, res_ns, -1, -1);
- printf(" error before (nsec):\n");
- print_nsec_error("min", stat->nsec_before_min, res_ns, nsec_before_min_tid,
- stat->nsec_before_min_idx);
- print_nsec_error("max", stat->nsec_before_max, res_ns, nsec_before_max_tid,
- stat->nsec_before_max_idx);
- print_nsec_error("ave", ave_before, res_ns, -1, -1);
-
- if (test_global->opt.mode == MODE_PERIODIC && !test_global->opt.offset_ns) {
- int idx = 0;
- int64_t max = 0;
-
- for (int i = 0; i < (int)test_global->opt.alloc_timers; i++) {
- timer_ctx_t *t = &test_global->timer_ctx[i];
- int64_t v = t->first_tmo_diff;
-
- if (ODPH_ABS(v) > ODPH_ABS(max)) {
- max = v;
- idx = i;
- }
- }
-
- printf(" first timeout difference to one period, based on %s (nsec):\n",
- test_global->timer_ctx[idx].tmo_tick ? "timeout tick" : "time");
- print_nsec_error("max", max, res_ns, -1, -1);
- }
-
- int64_t max = 0;
-
- for (int i = 0; i < (int)test_global->opt.alloc_timers; i++) {
- timer_ctx_t *t = &test_global->timer_ctx[i];
- int64_t v = t->nsec_final;
-
- if (ODPH_ABS(v) > ODPH_ABS(max))
- max = v;
- }
-
- printf(" final timeout error (nsec):\n");
- print_nsec_error("max", max, res_ns, -1, -1);
-
- printf("\n");
-}
-
-static void cancel_periodic_timers(test_global_t *test_global)
-{
- uint64_t i, alloc_timers;
- odp_timer_t timer;
-
- alloc_timers = test_global->opt.alloc_timers;
-
- for (i = 0; i < alloc_timers; i++) {
- timer = test_global->timer_ctx[i].timer;
-
- if (timer == ODP_TIMER_INVALID)
- break;
-
- if (odp_timer_periodic_cancel(timer))
- printf("Failed to cancel periodic timer.\n");
- }
-}
-
-static int run_test(void *arg)
-{
- test_global_t *test_global = (test_global_t *)arg;
- odp_event_t ev;
- odp_time_t time;
- uint64_t time_ns, diff_ns;
- odp_timeout_t tmo;
- uint64_t tmo_ns;
- timer_ctx_t *ctx;
- odp_thrmask_t mask;
- uint64_t wait = odp_schedule_wait_time(10 * ODP_TIME_MSEC_IN_NS);
- odp_schedule_group_t group = ODP_SCHED_GROUP_INVALID;
- test_log_t *log = test_global->log;
- enum mode_e mode = test_global->opt.mode;
- uint64_t tot_timers = test_global->opt.tot_timers;
- double period_dbl = test_global->period_dbl;
- odp_timer_pool_t tp = test_global->timer_pool;
- int tid = odp_thread_id();
-
- if (tid > test_global->opt.cpu_count) {
- printf("Error: tid %d is larger than cpu_count %d.\n", tid,
- test_global->opt.cpu_count);
- return 0;
- }
-
- test_stat_t *stat = &test_global->stat[tid];
-
- memset(stat, 0, sizeof(*stat));
- stat->nsec_before_min = UINT64_MAX;
- stat->nsec_after_min = UINT64_MAX;
-
- if (test_global->opt.groups) {
- odp_thrmask_zero(&mask);
- odp_thrmask_set(&mask, tid);
- group = test_global->group[tid - 1];
-
- if (odp_schedule_group_join(group, &mask)) {
- printf("odp_schedule_group_join() failed\n");
- return 0;
- }
- }
-
- odp_barrier_wait(&test_global->barrier);
-
- while (1) {
- ev = odp_schedule(NULL, wait);
- time = odp_time_global_strict();
-
- if (ev == ODP_EVENT_INVALID) {
- if (mode == MODE_PERIODIC) {
- if (odp_atomic_load_u64(&test_global->last_events) >=
- test_global->opt.alloc_timers)
- break;
-
- } else if (odp_atomic_load_u64(&test_global->events) >= tot_timers) {
- break;
- }
-
- continue;
- }
-
- time_ns = odp_time_to_ns(time);
- tmo = odp_timeout_from_event(ev);
- ctx = odp_timeout_user_ptr(tmo);
- tmo_ns = ctx->nsec;
-
- if (mode == MODE_PERIODIC) {
- if (!ctx->count && !test_global->opt.offset_ns) {
- /*
- * If first_tick is zero, the API allows the implementation to
- * place the timer where it can, so we have to adjust our
- * expectation of the timeout time.
- */
-
- uint64_t tmo_tick = odp_timeout_tick(tmo);
-
- if (tmo_tick) {
- /*
- * Adjust by the difference between one period after start
- * time and the timeout tick.
- */
- ctx->tmo_tick = 1;
- ctx->first_tmo_diff =
- (int64_t)odp_timer_tick_to_ns(tp, tmo_tick) -
- (int64_t)odp_timer_tick_to_ns(tp, ctx->first_period);
- tmo_ns += ctx->first_tmo_diff;
- } else {
- /*
- * Timeout tick is not provided, so the best we can do is
- * to just take the current time as a baseline.
- */
- ctx->first_tmo_diff = (int64_t)time_ns - (int64_t)tmo_ns;
- tmo_ns = ctx->nsec = time_ns;
- }
-
- ctx->nsec = tmo_ns;
- }
-
- /* round to closest integer number */
- tmo_ns += ctx->count * period_dbl + 0.5;
- ctx->count++;
- }
-
- uint64_t events = odp_atomic_fetch_inc_u64(&test_global->events);
-
- if (events >= test_global->opt.warmup_timers && events < tot_timers) {
- uint64_t i = events - test_global->opt.warmup_timers;
-
- ctx->nsec_final = (int64_t)time_ns - (int64_t)tmo_ns;
-
- if (log) {
- log[i].tmo_ns = tmo_ns;
- log[i].tid = tid;
- }
-
- if (time_ns > tmo_ns) {
- diff_ns = time_ns - tmo_ns;
- stat->num_after++;
- stat->nsec_after_sum += diff_ns;
- if (diff_ns < stat->nsec_after_min) {
- stat->nsec_after_min = diff_ns;
- stat->nsec_after_min_idx = i;
- }
- if (diff_ns > stat->nsec_after_max) {
- stat->nsec_after_max = diff_ns;
- stat->nsec_after_max_idx = i;
- }
- if (log)
- log[i].diff_ns = diff_ns;
-
- } else if (time_ns < tmo_ns) {
- diff_ns = tmo_ns - time_ns;
- stat->num_before++;
- stat->nsec_before_sum += diff_ns;
- if (diff_ns < stat->nsec_before_min) {
- stat->nsec_before_min = diff_ns;
- stat->nsec_before_min_idx = i;
- }
- if (diff_ns > stat->nsec_before_max) {
- stat->nsec_before_max = diff_ns;
- stat->nsec_before_max_idx = i;
- }
- if (log)
- log[i].diff_ns = -diff_ns;
- } else {
- stat->num_exact++;
- }
- }
-
- if ((mode == MODE_RESTART_ABS || mode == MODE_RESTART_REL) &&
- events < tot_timers - 1) {
- /* Reset timer for next period */
- odp_timer_t tim;
- uint64_t nsec, tick;
- odp_timer_retval_t ret;
- unsigned int j;
- unsigned int retries = test_global->opt.early_retry;
- uint64_t start_ns = test_global->start_ns;
- uint64_t period_ns = test_global->opt.period_ns;
- odp_timer_start_t start_param;
-
- tim = ctx->timer;
-
- /* Depending on the option, retry when expiration
- * time is too early */
- for (j = 0; j < retries + 1; j++) {
- if (mode == MODE_RESTART_ABS) {
- /* Absolute time */
- ctx->nsec += period_ns;
- nsec = ctx->nsec - start_ns;
- tick = test_global->start_tick +
- odp_timer_ns_to_tick(tp, nsec);
- start_param.tick_type = ODP_TIMER_TICK_ABS;
- } else {
- /* Relative time */
- tick = test_global->period_tick;
- time = odp_time_local();
- time_ns = odp_time_to_ns(time);
- ctx->nsec = time_ns + period_ns;
- start_param.tick_type = ODP_TIMER_TICK_REL;
- }
-
- start_param.tmo_ev = ev;
- start_param.tick = tick;
-
- ret = odp_timer_start(tim, &start_param);
- if (ret == ODP_TIMER_TOO_NEAR) {
- if (events >= test_global->opt.warmup_timers)
- stat->num_too_near++;
- } else {
- break;
- }
- }
-
- if (ret != ODP_TIMER_SUCCESS) {
- printf("Timer set failed: %i. Timeout nsec "
- "%" PRIu64 "\n", ret, ctx->nsec);
- return 0;
- }
- } else if (mode == MODE_PERIODIC) {
- int ret = odp_timer_periodic_ack(ctx->timer, ev);
-
- if (ret < 0)
- printf("Failed to ack a periodic timer.\n");
-
- if (ret == 2)
- odp_atomic_inc_u64(&test_global->last_events);
-
- if (ret == 2 || ret < 0)
- odp_event_free(ev);
- } else {
- odp_event_free(ev);
- }
- }
-
- if (test_global->opt.groups) {
- if (odp_schedule_group_leave(group, &mask))
- printf("odp_schedule_group_leave() failed\n");
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- odp_instance_t instance;
- odp_init_t init;
- test_opt_t test_opt;
- test_global_t *test_global;
- odph_helper_options_t helper_options;
- odp_init_t *init_ptr = NULL;
- int ret = 0;
-
- /* Let helper collect its own arguments (e.g. --odph_proc) */
- argc = odph_parse_options(argc, argv);
- if (odph_options(&helper_options)) {
- ODPH_ERR("Reading ODP helper options failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (parse_options(argc, argv, &test_opt))
- return -1;
-
- /* List features not to be used (may optimize performance) */
- odp_init_param_init(&init);
- init.not_used.feat.cls = 1;
- init.not_used.feat.compress = 1;
- init.not_used.feat.crypto = 1;
- init.not_used.feat.ipsec = 1;
- init.not_used.feat.tm = 1;
-
- init.mem_model = helper_options.mem_model;
-
- if (test_opt.init)
- init_ptr = &init;
-
- /* Init ODP before calling anything else */
- if (odp_init_global(&instance, init_ptr, NULL)) {
- printf("Global init failed.\n");
- return -1;
- }
-
- /* Init this thread */
- if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
- printf("Local init failed.\n");
- return -1;
- }
-
- odp_sys_info_print();
-
- /* Configure scheduler */
- odp_schedule_config(NULL);
-
- odp_shm_t shm = ODP_SHM_INVALID, shm_ctx = ODP_SHM_INVALID, shm_log = ODP_SHM_INVALID;
- uint64_t size = sizeof(test_global_t);
-
- shm = odp_shm_reserve("timer_accuracy", size,
- ODP_CACHE_LINE_SIZE, ODP_SHM_SINGLE_VA);
-
- if (shm == ODP_SHM_INVALID) {
- printf("Shm alloc failed.\n");
- return -1;
- }
-
- test_global = odp_shm_addr(shm);
- memset(test_global, 0, size);
- memcpy(&test_global->opt, &test_opt, sizeof(test_opt_t));
-
- size = test_global->opt.alloc_timers * sizeof(timer_ctx_t);
- shm_ctx = odp_shm_reserve("timer_accuracy_ctx", size,
- ODP_CACHE_LINE_SIZE, ODP_SHM_SINGLE_VA);
-
- if (shm_ctx == ODP_SHM_INVALID) {
- printf("Timer context alloc failed.\n");
- ret = -1;
- goto quit;
- }
-
- test_global->timer_ctx = odp_shm_addr(shm_ctx);
- memset(test_global->timer_ctx, 0, size);
-
- if (test_global->opt.output) {
- test_global->file = fopen(test_global->opt.filename, "w");
- if (test_global->file == NULL) {
- printf("Failed to open output file %s: %s\n",
- test_global->opt.filename, strerror(errno));
- ret = -1;
- goto quit;
- }
-
- size = (test_global->opt.tot_timers - test_global->opt.warmup_timers) *
- sizeof(test_log_t);
- shm_log = odp_shm_reserve("timer_accuracy_log", size, sizeof(test_log_t),
- ODP_SHM_SINGLE_VA);
-
- if (shm_log == ODP_SHM_INVALID) {
- printf("Test log alloc failed.\n");
- ret = -1;
- goto quit;
- }
-
- test_global->log = odp_shm_addr(shm_log);
- memset(test_global->log, 0, size);
- }
-
- odph_thread_t thread_tbl[MAX_WORKERS];
- int num_workers;
- odp_cpumask_t cpumask;
- char cpumaskstr[ODP_CPUMASK_STR_SIZE];
- odph_thread_common_param_t thr_common;
- odph_thread_param_t thr_param;
-
- memset(thread_tbl, 0, sizeof(thread_tbl));
-
- num_workers = MAX_WORKERS;
- if (test_global->opt.cpu_count && test_global->opt.cpu_count < MAX_WORKERS)
- num_workers = test_global->opt.cpu_count;
- num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
- test_global->opt.cpu_count = num_workers;
- odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
-
- printf("num worker threads: %i\n", num_workers);
- printf("first CPU: %i\n", odp_cpumask_first(&cpumask));
- printf("cpu mask: %s\n", cpumaskstr);
-
- ret = create_timers(test_global);
- if (ret)
- goto quit;
-
- odp_barrier_init(&test_global->barrier, num_workers + 1);
- odp_atomic_init_u64(&test_global->events, 0);
- odp_atomic_init_u64(&test_global->last_events, 0);
-
- odph_thread_param_init(&thr_param);
- thr_param.start = run_test;
- thr_param.arg = (void *)test_global;
- thr_param.thr_type = ODP_THREAD_WORKER;
-
- odph_thread_common_param_init(&thr_common);
- thr_common.instance = instance;
- thr_common.cpumask = &cpumask;
- thr_common.share_param = 1;
-
- odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
- odp_barrier_wait(&test_global->barrier);
-
- ret = start_timers(test_global);
- if (ret)
- goto quit;
-
- if (test_global->opt.mode == MODE_PERIODIC) {
- while (odp_atomic_load_u64(&test_global->events) < test_global->opt.tot_timers)
- odp_time_wait_ns(10 * ODP_TIME_MSEC_IN_NS);
-
- cancel_periodic_timers(test_global);
- }
-
- odph_thread_join(thread_tbl, num_workers);
- print_stat(test_global);
-
-quit:
- if (test_global->file)
- fclose(test_global->file);
-
- if (destroy_timers(test_global))
- ret = -1;
-
- if (shm_log != ODP_SHM_INVALID && odp_shm_free(shm_log))
- ret = -1;
-
- if (shm_ctx != ODP_SHM_INVALID && odp_shm_free(shm_ctx))
- ret = -1;
-
- if (odp_shm_free(shm))
- ret = -1;
-
- if (odp_term_local()) {
- printf("Term local failed.\n");
- ret = -1;
- }
-
- if (odp_term_global(instance)) {
- printf("Term global failed.\n");
- ret = -1;
- }
-
- return ret;
-}
diff --git a/example/timer/odp_timer_accuracy_run.sh b/example/timer/odp_timer_accuracy_run.sh
deleted file mode 100755
index 1c879f4e6..000000000
--- a/example/timer/odp_timer_accuracy_run.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-#
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright (c) 2022 Nokia
-#
-
-./odp_timer_accuracy${EXEEXT} -p 100000000 -n 10
diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
deleted file mode 100644
index 674d4f4ce..000000000
--- a/example/timer/odp_timer_test.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2013-2018 Linaro Limited
- */
-
-/**
- * @example odp_timer_test.c
- *
- * Timer test application
- *
- * @cond _ODP_HIDE_FROM_DOXYGEN_
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-/* ODP main header */
-#include <odp_api.h>
-
-/* ODP helper for Linux apps */
-#include <odp/helper/odph_api.h>
-
-/* GNU lib C */
-#include <getopt.h>
-
-/* Max worker threads */
-#define MAX_WORKERS (ODP_THREAD_COUNT_MAX - 1)
-#define NUM_TMOS 10000 /**< Number of timers */
-#define WAIT_NUM 10 /**< Max tries to rx last tmo per worker */
-
-/** Test arguments */
-typedef struct {
- unsigned int cpu_count; /**< CPU count*/
- int resolution_us; /**< Timeout resolution in usec*/
- int min_us; /**< Minimum timeout in usec*/
- int max_us; /**< Maximum timeout in usec*/
- int period_us; /**< Timeout period in usec*/
- int tmo_count; /**< Timeout count*/
-} test_args_t;
-
-/** @private Helper struct for timers */
-struct test_timer {
- odp_timer_t tim;
- odp_event_t ev;
-};
-
-/** Test global variables */
-typedef struct {
- test_args_t args; /**< Test argunments*/
- odp_barrier_t test_barrier; /**< Barrier for test synchronisation*/
- odp_pool_t pool; /**< pool handle*/
- odp_timer_pool_t tp; /**< Timer pool handle*/
- odp_atomic_u32_t remain; /**< Number of timeouts to receive*/
- struct test_timer tt[256]; /**< Array of all timer helper structs*/
- uint32_t num_workers; /**< Number of threads */
-} test_globals_t;
-
-/** @private Timer set status ASCII strings */
-static const char *timerset2str(odp_timer_retval_t val)
-{
- switch (val) {
- case ODP_TIMER_SUCCESS:
- return "success";
- case ODP_TIMER_TOO_NEAR:
- return "too near";
- case ODP_TIMER_TOO_FAR:
- return "too far";
- case ODP_TIMER_FAIL:
- return "failure";
- default:
- return "?";
- }
-}
-
-/** @private test timeout */
-static void remove_prescheduled_events(void)
-{
- odp_event_t ev;
- odp_queue_t queue;
- odp_schedule_pause();
- while ((ev = odp_schedule(&queue, ODP_SCHED_NO_WAIT)) !=
- ODP_EVENT_INVALID) {
- odp_event_free(ev);
- }
-}
-
-/** @private test timeout */
-static void test_abs_timeouts(int thr, test_globals_t *gbls)
-{
- uint64_t period;
- uint64_t period_ns;
- odp_queue_t queue;
- uint64_t tick;
- struct test_timer *ttp;
- odp_timeout_t tmo;
- uint32_t num_workers = gbls->num_workers;
-
- ODPH_DBG(" [%i] test_timeouts\n", thr);
-
- queue = odp_queue_lookup("timer_queue");
-
- period_ns = gbls->args.period_us * ODP_TIME_USEC_IN_NS;
- period = odp_timer_ns_to_tick(gbls->tp, period_ns);
-
- ODPH_DBG(" [%i] period %" PRIu64 " ticks, %" PRIu64 " ns\n", thr,
- period, period_ns);
-
- ODPH_DBG(" [%i] current tick %" PRIu64 "\n", thr,
- odp_timer_current_tick(gbls->tp));
-
- ttp = &gbls->tt[thr];
- ttp->tim = odp_timer_alloc(gbls->tp, queue, ttp);
- if (ttp->tim == ODP_TIMER_INVALID) {
- ODPH_ERR("Failed to allocate timer\n");
- return;
- }
- tmo = odp_timeout_alloc(gbls->pool);
- if (tmo == ODP_TIMEOUT_INVALID) {
- ODPH_ERR("Failed to allocate timeout\n");
- return;
- }
- ttp->ev = odp_timeout_to_event(tmo);
- tick = odp_timer_current_tick(gbls->tp);
-
- while (1) {
- int wait = 0;
- odp_event_t ev;
- odp_timer_retval_t rc;
- odp_timer_start_t start_param;
-
- if (ttp) {
- tick += period;
-
- start_param.tick_type = ODP_TIMER_TICK_ABS;
- start_param.tick = tick;
- start_param.tmo_ev = ttp->ev;
-
- rc = odp_timer_start(ttp->tim, &start_param);
- if (odp_unlikely(rc != ODP_TIMER_SUCCESS)) {
- /* Too early or too late timeout requested */
- ODPH_ABORT("odp_timer_start() failed: %s\n", timerset2str(rc));
- }
- }
-
- /* Get the next expired timeout.
- * We invoke the scheduler in a loop with a timeout because
- * we are not guaranteed to receive any more timeouts. The
- * scheduler isn't guaranteeing fairness when scheduling
- * buffers to threads.
- * Use 1.5 second timeout for scheduler */
- uint64_t sched_tmo =
- odp_schedule_wait_time(1500000000ULL);
- do {
- ev = odp_schedule(&queue, sched_tmo);
- /* Check if odp_schedule() timed out, possibly there
- * are no remaining timeouts to receive */
- if (++wait > WAIT_NUM &&
- odp_atomic_load_u32(&gbls->remain) < num_workers)
- ODPH_ABORT("At least one TMO was lost\n");
- } while (ev == ODP_EVENT_INVALID &&
- (int)odp_atomic_load_u32(&gbls->remain) > 0);
-
- if (ev == ODP_EVENT_INVALID)
- break; /* No more timeouts */
- if (odp_event_type(ev) != ODP_EVENT_TIMEOUT) {
- /* Not a default timeout event */
- ODPH_ABORT("Unexpected event type (%u) received\n",
- odp_event_type(ev));
- }
- tmo = odp_timeout_from_event(ev);
- tick = odp_timeout_tick(tmo);
- ttp = odp_timeout_user_ptr(tmo);
- ttp->ev = ev;
-
- ODPH_DBG(" [%i] timeout, tick %" PRIu64 "\n", thr, tick);
-
- uint32_t rx_num = odp_atomic_fetch_dec_u32(&gbls->remain);
-
- if (!rx_num)
- ODPH_ABORT("Unexpected timeout received (timer "
- "%" PRIu64 ", tick %" PRIu64 ")\n",
- odp_timer_to_u64(ttp->tim), tick);
- else if (rx_num > num_workers)
- continue;
-
- odp_event_free(ttp->ev);
-
- if (odp_timer_free(ttp->tim))
- ODPH_ABORT("Timer free failed (%" PRIu64 ")\n", odp_timer_to_u64(ttp->tim));
-
- ttp = NULL;
- }
-
- /* Remove any prescheduled events */
- remove_prescheduled_events();
-}
-
-
-/**
- * @internal Worker thread
- *
- * @param ptr Pointer to test arguments
- *
- * @return Pointer to exit status
- */
-static int run_thread(void *ptr)
-{
- int thr;
- odp_pool_t msg_pool;
- test_globals_t *gbls;
-
- gbls = ptr;
- thr = odp_thread_id();
-
- printf("Thread %i starts on cpu %i\n", thr, odp_cpu_id());
-
- /*
- * Find the pool
- */
- msg_pool = odp_pool_lookup("msg_pool");
-
- if (msg_pool == ODP_POOL_INVALID) {
- ODPH_ERR(" [%i] msg_pool not found\n", thr);
- return -1;
- }
-
- odp_barrier_wait(&gbls->test_barrier);
-
- test_abs_timeouts(thr, gbls);
-
-
- printf("Thread %i exits\n", thr);
- fflush(NULL);
- return 0;
-}
-
-
-/**
- * @internal Print help
- */
-static void print_usage(void)
-{
- printf("\n\nUsage: ./odp_example [options]\n");
- printf("Options:\n");
- printf(" -c, --count <number> CPU count, 0=all available, default=1\n");
- printf(" -r, --resolution <us> timeout resolution in usec\n");
- printf(" -m, --min <us> minimum timeout in usec\n");
- printf(" -x, --max <us> maximum timeout in usec\n");
- printf(" -p, --period <us> timeout period in usec\n");
- printf(" -t, --timeouts <count> timeout repeat count\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 int parse_args(int argc, char *argv[], test_args_t *args)
-{
- int opt;
- int long_index;
- odp_timer_capability_t timer_capa;
-
- static const struct option longopts[] = {
- {"count", required_argument, NULL, 'c'},
- {"resolution", required_argument, NULL, 'r'},
- {"min", required_argument, NULL, 'm'},
- {"max", required_argument, NULL, 'x'},
- {"period", required_argument, NULL, 'p'},
- {"timeouts", required_argument, NULL, 't'},
- {"help", no_argument, NULL, 'h'},
- {NULL, 0, NULL, 0}
- };
-
- static const char *shortopts = "+c:r:m:x:p:t:h";
-
- /* defaults */
- if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa))
- return -1;
-
- args->cpu_count = 1;
- args->resolution_us = ODPH_MAX(10000u, timer_capa.highest_res_ns / ODP_TIME_USEC_IN_NS);
- args->min_us = 0;
- args->max_us = 10000000;
- args->period_us = 1000000;
- args->tmo_count = 30;
-
- while (1) {
- opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
-
- if (opt == -1)
- break; /* No more options */
-
- switch (opt) {
- case 'c':
- args->cpu_count = atoi(optarg);
- break;
- case 'r':
- args->resolution_us = atoi(optarg);
- break;
- case 'm':
- args->min_us = atoi(optarg);
- break;
- case 'x':
- args->max_us = atoi(optarg);
- break;
- case 'p':
- args->period_us = atoi(optarg);
- break;
- case 't':
- args->tmo_count = atoi(optarg);
- break;
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- default:
- break;
- }
- }
-
- if (args->period_us < args->resolution_us)
- printf("\n\tWarn: timeout is set less then resolution\n");
-
- return 0;
-}
-
-/**
- * Test main function
- */
-int main(int argc, char *argv[])
-{
- odph_helper_options_t helper_options;
- odph_thread_t thread_tbl[MAX_WORKERS];
- odph_thread_common_param_t thr_common;
- odph_thread_param_t thr_param;
- int num_workers;
- odp_queue_t queue;
- uint64_t tick, ns;
- odp_queue_param_t param;
- odp_pool_param_t params;
- odp_timer_pool_param_t tparams;
- odp_timer_pool_info_t tpinfo;
- odp_cpumask_t cpumask;
- char cpumaskstr[ODP_CPUMASK_STR_SIZE];
- odp_instance_t instance;
- odp_init_t init_param;
- odp_shm_t shm = ODP_SHM_INVALID;
- test_globals_t *gbls = NULL;
- int err = 0;
-
- printf("\nODP timer example starts\n");
-
- /* 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_param_init(&init_param);
- init_param.mem_model = helper_options.mem_model;
-
- if (odp_init_global(&instance, &init_param, NULL)) {
- err = 1;
- printf("ODP global init failed.\n");
- goto err_global;
- }
-
- /* Init this thread. */
- if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
- err = 1;
- printf("ODP local init failed.\n");
- goto err_local;
- }
-
- printf("\n");
- odp_sys_info_print();
-
- /* Reserve memory for test_globals_t from shared mem */
- shm = odp_shm_reserve("shm_test_globals", sizeof(test_globals_t),
- ODP_CACHE_LINE_SIZE, 0);
- if (ODP_SHM_INVALID == shm) {
- err = 1;
- ODPH_ERR("Error: shared mem reserve failed.\n");
- goto err;
- }
-
- gbls = odp_shm_addr(shm);
- if (NULL == gbls) {
- err = 1;
- ODPH_ERR("Error: shared mem alloc failed.\n");
- goto err;
- }
- memset(gbls, 0, sizeof(test_globals_t));
- gbls->pool = ODP_POOL_INVALID;
- gbls->tp = ODP_TIMER_POOL_INVALID;
-
- if (parse_args(argc, argv, &gbls->args)) {
- ODPH_ERR("Parse args failed.\n");
- goto err;
- }
-
- memset(thread_tbl, 0, sizeof(thread_tbl));
-
- num_workers = MAX_WORKERS;
- if (gbls->args.cpu_count && gbls->args.cpu_count < MAX_WORKERS)
- num_workers = gbls->args.cpu_count;
-
- /* Get default worker cpumask */
- num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
- (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
-
- printf("num worker threads: %i\n", num_workers);
- printf("first CPU: %i\n", odp_cpumask_first(&cpumask));
- printf("cpu mask: %s\n", cpumaskstr);
-
- printf("resolution: %i usec\n", gbls->args.resolution_us);
- printf("min timeout: %i usec\n", gbls->args.min_us);
- printf("max timeout: %i usec\n", gbls->args.max_us);
- printf("period: %i usec\n", gbls->args.period_us);
- printf("timeouts: %i\n", gbls->args.tmo_count);
-
- /* Configure scheduler */
- odp_schedule_config(NULL);
-
- /*
- * Create pool for timeouts
- */
- odp_pool_param_init(&params);
- params.tmo.num = NUM_TMOS;
- params.type = ODP_POOL_TIMEOUT;
-
- gbls->pool = odp_pool_create("msg_pool", &params);
-
- if (gbls->pool == ODP_POOL_INVALID) {
- err = 1;
- ODPH_ERR("Pool create failed.\n");
- goto err;
- }
-
- odp_timer_pool_param_init(&tparams);
- tparams.res_ns = gbls->args.resolution_us * ODP_TIME_USEC_IN_NS;
- tparams.min_tmo = gbls->args.min_us * ODP_TIME_USEC_IN_NS;
- tparams.max_tmo = gbls->args.max_us * ODP_TIME_USEC_IN_NS;
- tparams.num_timers = num_workers; /* One timer per worker */
- tparams.priv = 0; /* Shared */
- tparams.clk_src = ODP_CLOCK_DEFAULT;
-
- gbls->tp = odp_timer_pool_create("timer_pool", &tparams);
- if (gbls->tp == ODP_TIMER_POOL_INVALID) {
- err = 1;
- ODPH_ERR("Timer pool create failed.\n");
- goto err;
- }
-
- if (odp_timer_pool_start_multi(&gbls->tp, 1) != 1) {
- ODPH_ERR("Timer pool start failed\n");
- return -1;
- }
-
- odp_shm_print_all();
- (void)odp_timer_pool_info(gbls->tp, &tpinfo);
- printf("Timer pool\n");
- printf("----------\n");
- printf(" name: %s\n", tpinfo.name);
- printf(" resolution: %"PRIu64" ns\n", tpinfo.param.res_ns);
- printf(" min tmo: %"PRIu64" ticks\n", tpinfo.param.min_tmo);
- printf(" max tmo: %"PRIu64" ticks\n", tpinfo.param.max_tmo);
- printf("\n");
-
- /*
- * Create a queue for timer test
- */
- odp_queue_param_init(&param);
- param.type = ODP_QUEUE_TYPE_SCHED;
- param.sched.prio = odp_schedule_default_prio();
- param.sched.sync = ODP_SCHED_SYNC_PARALLEL;
- param.sched.group = ODP_SCHED_GROUP_ALL;
-
- queue = odp_queue_create("timer_queue", &param);
-
- if (queue == ODP_QUEUE_INVALID) {
- err = 1;
- ODPH_ERR("Timer queue create failed.\n");
- goto err;
- }
-
- printf("CPU freq %"PRIu64" Hz\n", odp_cpu_hz_max());
- printf("Timer ticks vs nanoseconds:\n");
- ns = 0;
- tick = odp_timer_ns_to_tick(gbls->tp, ns);
-
- printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, tick);
- printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick,
- odp_timer_tick_to_ns(gbls->tp, tick));
-
- for (ns = 1; ns <= 100 * ODP_TIME_SEC_IN_NS; ns *= 10) {
- tick = odp_timer_ns_to_tick(gbls->tp, ns);
-
- printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns,
- tick);
- printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick,
- odp_timer_tick_to_ns(gbls->tp, tick));
- }
-
- printf("\n");
-
- gbls->num_workers = num_workers;
-
- /* Initialize number of timeouts to receive */
- odp_atomic_init_u32(&gbls->remain, gbls->args.tmo_count * num_workers);
-
- /* Barrier to sync test case execution */
- odp_barrier_init(&gbls->test_barrier, num_workers);
-
- /* Create and launch worker threads */
- odph_thread_common_param_init(&thr_common);
- thr_common.instance = instance;
- thr_common.cpumask = &cpumask;
- thr_common.share_param = 1;
-
- odph_thread_param_init(&thr_param);
- thr_param.start = run_thread;
- thr_param.arg = gbls;
- thr_param.thr_type = ODP_THREAD_WORKER;
-
- odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
-
- /* Wait for worker threads to exit */
- odph_thread_join(thread_tbl, num_workers);
-
- /* free resources */
- if (odp_queue_destroy(queue))
- err = 1;
-
-err:
-
- if (gbls != NULL && gbls->tp != ODP_TIMER_POOL_INVALID)
- odp_timer_pool_destroy(gbls->tp);
-
- if (gbls != NULL && gbls->pool != ODP_POOL_INVALID)
- if (odp_pool_destroy(gbls->pool))
- err = 1;
-
- if (shm != ODP_SHM_INVALID)
- if (odp_shm_free(shm))
- err = 1;
-
- if (odp_term_local())
- err = 1;
-err_local:
- if (odp_term_global(instance))
- err = 1;
-err_global:
- if (err) {
- printf("Err: ODP timer test failed\n\n");
- return -1;
- }
-
- printf("ODP timer test complete\n\n");
- return 0;
-}
diff --git a/example/traffic_mgmt/odp_traffic_mgmt.c b/example/traffic_mgmt/odp_traffic_mgmt.c
index 4ed4f2044..17dcbaa13 100644
--- a/example/traffic_mgmt/odp_traffic_mgmt.c
+++ b/example/traffic_mgmt/odp_traffic_mgmt.c
@@ -343,7 +343,7 @@ static uint32_t create_profile_set(profile_params_set_t *profile_params_set,
odp_tm_shaper_params_t shaper_params, *shaper;
odp_tm_wred_params_t wred_params, *wred;
uint32_t err_cnt, color;
- char name[64], wred_name[64];
+ char name[ODP_TM_NAME_LEN], wred_name[ODP_TM_NAME_LEN];
err_cnt = 0;
if (name_idx == 0)
@@ -477,7 +477,7 @@ static int config_example_user(odp_tm_node_t cos_tm_node,
odp_tm_node_t user_tm_node;
profile_set_t *profile_set;
uint32_t app_idx, queue_idx, svc_class_queue_num;
- char user_name[64];
+ char user_name[ODP_TM_NAME_LEN];
int rc;
profile_set = &USER_PROFILE_SETS[svc_class];
@@ -538,7 +538,7 @@ static int config_company_node(const char *company_name)
profile_set_t *profile_set;
odp_tm_node_t company_tm_node, cos_tm_node;
uint32_t cos_idx, user_idx;
- char cos_node_name[64];
+ char cos_node_name[ODP_TM_NAME_LEN];
profile_set = &COMPANY_PROFILE_SET;
odp_tm_node_params_init(&tm_node_params);