Stress test for benchmarking timer related handling performance in different scenarios.
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <odp/helper/odph_api.h>
#define PROG_NAME "odp_timer_stress"
#define MAX_WORKERS ((uint32_t)(ODP_THREAD_COUNT_MAX - 1))
#define MULTIPLIER 50U
#define FMT_RES "4"
#define MAX_RETRY 10U
#define WAIT_MULTIPLIER 100U
#define GIGAS 1000000000U
#define MEGAS 1000000U
#define KILOS 1000U
enum {
SINGLE_SHOT,
PERIODIC,
CANCEL
};
enum {
SHARED_TMR,
PRIV_TMR
};
#define DEF_MODE SINGLE_SHOT
#define DEF_CLK_SRC ODP_CLOCK_DEFAULT
#define DEF_RES 1000000U
#define DEF_TIMERS 50U
#define DEF_POLICY SHARED_TMR
#define DEF_TIME 2U
#define DEF_WORKERS 1U
#define ROUNDUP_DIV(a, b) (((a) + ((b) - 1)) / (b))
typedef enum {
PRS_OK,
PRS_NOK,
PRS_TERM
} parse_result_t;
typedef struct {
uint64_t num_tmo;
uint64_t num_retry;
uint64_t num_miss;
uint64_t tot_tm;
uint64_t max_mul;
} stats_t;
typedef struct prog_config_s prog_config_t;
typedef struct {
} tmr_hdls_t;
stats_t stats;
struct {
} scd;
struct {
tmr_hdls_t *tmrs;
} cancel;
prog_config_t *prog_config;
uint32_t num_boot_tmr;
} worker_config_t;
typedef struct {
uint32_t mode;
uint64_t res_ns;
uint32_t num_tmr;
uint32_t policy;
uint32_t time_sec;
uint32_t num_workers;
} opts_t;
typedef struct prog_config_s {
odph_thread_t thread_tbl[MAX_WORKERS];
worker_config_t worker_config[MAX_WORKERS];
opts_t def_opts;
opts_t opts;
} prog_config_t;
static prog_config_t *prog_conf;
{
}
static void init_config(prog_config_t *config)
{
opts_t opts;
worker_config_t *worker;
opts.mode = DEF_MODE;
opts.clk_src = DEF_CLK_SRC;
opts.res_ns = DEF_RES;
opts.num_tmr = DEF_TIMERS;
opts.policy = DEF_POLICY;
opts.time_sec = DEF_TIME;
opts.num_workers = DEF_WORKERS;
if (opts.mode == SINGLE_SHOT || opts.mode == CANCEL) {
}
}
for (uint32_t i = 0U; i < MAX_WORKERS; ++i) {
worker = &config->worker_config[i];
}
config->def_opts = opts;
config->opts = config->def_opts;
}
static void print_usage(const opts_t *opts)
{
printf("\n"
"Stress test for benchmarking timer related handling performance in different\n"
"scenarios.\n"
"\n"
"Usage: " PROG_NAME " [OPTIONS]\n");
printf("\n"
" E.g. " PROG_NAME " -m 0 -n 20\n"
" " PROG_NAME " -m 2 -p 1 -t 5 -c 4\n");
printf("\n"
"Optional OPTIONS:\n"
"\n"
" -m, --mode Timer mode. %u by default. Modes:\n"
" 0: single shot\n"
" 1: periodic\n"
" 2: single shot with cancel\n"
" -s, --clock_source Clock source. Use 'odp_timer_clk_src_t' enumeration values.\n"
" %u by default.\n"
" -r, --resolution Timer resolution in nanoseconds. %" PRIu64 " by default.\n"
" -n, --num_timer Number of timers. %u by default.\n"
" -p, --policy Timer sharing policy. %u by default. Policies:\n"
" 0: Timers shared by workers\n"
" 1: Private timers per worker\n"
" -t, --time_sec Time in seconds to run. 0 means infinite. %u by default.\n"
" -c, --worker_count Number of workers. %u by default.\n"
" -h, --help This help.\n"
"\n", opts->mode, opts->clk_src, opts->res_ns, opts->num_tmr, opts->policy,
opts->time_sec, opts->num_workers);
}
{
double leftover;
fract.
numer = (uint64_t)(leftover * DEF_RES);
return fract;
}
static parse_result_t check_options(prog_config_t *config)
{
opts_t *opts = &config->opts;
int ret;
uint32_t req_tmr, max_workers, req_shm;
double hz_d, min_hz_d, max_hz_d;
uint64_t req_shm_sz;
if (opts->mode != SINGLE_SHOT && opts->mode != PERIODIC && opts->mode != CANCEL) {
ODPH_ERR("Invalid timer mode: %u\n", opts->mode);
return PRS_NOK;
}
if (opts->policy != SHARED_TMR && opts->policy != PRIV_TMR) {
ODPH_ERR("Invalid pool policy: %d\n", opts->policy);
return PRS_NOK;
}
if (opts->mode == CANCEL && opts->policy != PRIV_TMR) {
ODPH_ERR("Single shot with cancel mode supported only with worker-private "
"timers\n");
return PRS_NOK;
}
if (ret < -1) {
ODPH_ERR("Error querying timer capabilities\n");
return PRS_NOK;
}
if (ret == -1) {
ODPH_ERR("Invalid clock source: %d\n", opts->clk_src);
return PRS_NOK;
}
ODPH_ERR("Invalid queue support, scheduled completion queues not supported\n");
return PRS_NOK;
}
ODPH_ERR("Invalid resolution: %" PRIu64 " ns (max: %" PRIu64 " ns)\n",
return PRS_NOK;
}
if (opts->num_tmr == 0U) {
ODPH_ERR("Invalid number of timers: %u\n", opts->num_tmr);
return PRS_NOK;
}
if (opts->num_workers == 0U || opts->num_workers > max_workers) {
ODPH_ERR("Invalid worker count: %u (min: 1, max: %u)\n", opts->num_workers,
max_workers);
return PRS_NOK;
}
req_tmr = opts->num_tmr * (opts->policy == PRIV_TMR ? opts->num_workers : 1U);
if (opts->mode == SINGLE_SHOT || opts->mode == CANCEL) {
ODPH_ERR("Single shot timers not supported\n");
return PRS_NOK;
}
ODPH_ERR("Invalid number of timers: %u (max: %u)\n", req_tmr,
return PRS_NOK;
}
config->res_capa.res_ns = opts->res_ns;
ODPH_ERR("Error querying timer resolution capabilities\n");
return PRS_NOK;
}
if (opts->mode == CANCEL) {
ODPH_ERR("Error querying SHM capabilities");
return PRS_NOK;
}
req_shm = 2U;
ODPH_ERR("Invalid SHM block count support: %u (max: %u)\n",
return PRS_NOK;
}
opts->num_tmr * opts->num_workers;
ODPH_ERR("Invalid total SHM block size: %" PRIu64 ""
" (max: %" PRIu64
")\n", req_shm_sz, shm_capa.
max_size);
return PRS_NOK;
}
}
} else {
ODPH_ERR("Periodic timers not supported\n");
return PRS_NOK;
}
ODPH_ERR("Invalid number of timers: %u (max: %u)\n", req_tmr,
return PRS_NOK;
}
hz = calc_req_hz(opts->res_ns);
if (hz_d < min_hz_d || hz_d > max_hz_d) {
ODPH_ERR("Invalid requested resolution: %." FMT_RES "f hz "
"(min: %." FMT_RES "f hz, max: %." FMT_RES "f hz)\n", hz_d,
min_hz_d, max_hz_d);
return PRS_NOK;
}
config->per_capa.base_freq_hz = hz;
config->per_capa.max_multiplier = MULTIPLIER;
config->per_capa.res_ns = opts->res_ns;
ODPH_ERR("Error querying periodic timer capabilities\n");
return PRS_NOK;
}
if (config->per_capa.max_multiplier > MULTIPLIER)
config->per_capa.max_multiplier = MULTIPLIER;
}
ODPH_ERR("Error querying pool capabilities\n");
return PRS_NOK;
}
ODPH_ERR("Invalid timeout event count: %u (max: %u)\n", req_tmr,
return PRS_NOK;
}
return PRS_OK;
}
static parse_result_t parse_options(int argc, char **argv, prog_config_t *config)
{
int opt;
opts_t *opts = &config->opts;
static const struct option longopts[] = {
{ "mode", required_argument, NULL, 'm' },
{ "clock_source", required_argument, NULL, 's' },
{ "resolution", required_argument, NULL, 'r' },
{ "num_timer", required_argument, NULL, 'n' },
{ "policy", required_argument, NULL, 'p' },
{ "time_sec", required_argument, NULL, 't' },
{ "worker_count", required_argument, NULL, 'c' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
static const char *shortopts = "m:s:r:n:p:t:c:h";
init_config(config);
while (true) {
opt = getopt_long(argc, argv, shortopts, longopts, NULL);
if (opt == -1)
break;
switch (opt) {
case 'm':
opts->mode = atoi(optarg);
break;
case 's':
opts->clk_src = atoi(optarg);
break;
case 'r':
opts->res_ns = atoll(optarg);
break;
case 'n':
opts->num_tmr = atoi(optarg);
break;
case 'p':
opts->policy = atoi(optarg);
break;
case 't':
opts->time_sec = atoi(optarg);
break;
case 'c':
opts->num_workers = atoi(optarg);
break;
case 'h':
print_usage(&config->def_opts);
return PRS_TERM;
case '?':
default:
print_usage(&config->def_opts);
return PRS_NOK;
}
}
return check_options(config);
}
static parse_result_t setup_program(int argc, char **argv, prog_config_t *config)
{
struct sigaction action = { .sa_handler = terminate };
if (sigemptyset(&action.sa_mask) == -1 || sigaddset(&action.sa_mask, SIGINT) == -1 ||
sigaddset(&action.sa_mask, SIGTERM) == -1 ||
sigaddset(&action.sa_mask, SIGHUP) == -1 || sigaction(SIGINT, &action, NULL) == -1 ||
sigaction(SIGTERM, &action, NULL) == -1 || sigaction(SIGHUP, &action, NULL) == -1) {
ODPH_ERR("Error installing signal handler\n");
return PRS_NOK;
}
return parse_options(argc, argv, config);
}
{
ODPH_ERR("Error creating timer pool\n");
}
ODPH_ERR("Error starting timer pool\n");
}
return pool;
}
static odp_bool_t setup_config(prog_config_t *config)
{
opts_t *opts = &config->opts;
const uint32_t num_barrier = opts->num_workers + 1,
max_tmr = opts->num_tmr * (is_priv ? opts->num_workers : 1U),
void *cancel_addr = NULL;
uint32_t num_tmr_p_w = ROUNDUP_DIV(opts->num_tmr, opts->num_workers),
num_tmr = opts->num_tmr;
worker_config_t *worker;
ODPH_ERR("Error initializing scheduler\n");
return false;
}
ODPH_ERR("Error creating timeout pool\n");
return false;
}
tmr_param.
res_ns = opts->res_ns;
if (opts->mode == SINGLE_SHOT || opts->mode == CANCEL) {
tmr_param.
min_tmo = config->res_capa.min_tmo;
tmr_param.
max_tmo = config->res_capa.max_tmo;
} else {
}
config->tmr_pool = create_timer_pool(&tmr_param);
return false;
if (is_priv && opts->mode == CANCEL) {
ODP_CACHE_LINE_SIZE, 0U);
ODPH_ERR("Error reserving SHM for cancel mode\n");
return false;
}
if (cancel_addr == NULL) {
ODPH_ERR("Error resolving SHM address for cancel mode\n");
return false;
}
}
for (uint32_t i = 0U; i < opts->num_workers; ++i) {
worker = &config->worker_config[i];
worker->num_boot_tmr = num_tmr_p_w;
num_tmr -= num_tmr_p_w;
if (num_tmr < num_tmr_p_w)
num_tmr_p_w = num_tmr;
if (is_priv) {
worker->num_boot_tmr = opts->num_tmr;
if (opts->mode == CANCEL)
worker->cancel.tmrs =
(tmr_hdls_t *)(uintptr_t)((uint8_t *)(uintptr_t)cancel_addr + i *
worker->num_boot_tmr * tmr_size);
ODPH_ERR("Error creating schedule group for worker %u\n", i);
return false;
}
}
ODPH_ERR("Error creating completion queue for worker %u\n", i);
return false;
}
worker->prog_config = config;
}
return true;
}
{
tmr_hdls_t time;
ODPH_ABORT("Error allocating timers, aborting (tmr: %" PRIx64 ", "
ODPH_ABORT("Error allocating timeouts, aborting (tmo: %" PRIx64 ", "
time.is_running = true;
return time;
}
uint64_t res_ns, stats_t *stats)
{
uint32_t retry = MAX_RETRY, mul = 1U;
int ret;
while (retry) {
break;
--retry;
++mul;
++stats->num_retry;
continue;
}
ODPH_ABORT("Error starting timers, aborting (tmr: %" PRIx64 ", tmr pool: "
}
stats->max_mul = mul > stats->max_mul ? mul : stats->max_mul;
}
static void boot_single_shot(worker_config_t *worker,
odp_timer_pool_t tmr_pool,
{
tmr_hdls_t time;
for (uint32_t i = 0U; i < worker->num_boot_tmr; ++i) {
time = get_time_handles(tmr_pool, tmo_pool, worker->scd.q);
&worker->stats);
}
}
static int process_single_shot(void *args)
{
worker_config_t *worker = args;
prog_config_t *config = worker->prog_config;
const uint64_t res_ns = prog_conf->opts.res_ns;
stats_t *stats = &worker->stats;
ODPH_ABORT("Error joining scheduler group, aborting (group: %" PRIu64 ")"
}
boot_single_shot(worker, tmr_pool, config->tmo_pool, res_ns);
continue;
start_single_shot(tmr_pool, tmr, ev, res_ns, stats);
++stats->num_tmo;
}
while (true) {
WAIT_MULTIPLIER));
break;
}
return 0;
}
uint64_t mul)
{
ODPH_ABORT("Error starting timer, aborting (tmr: %" PRIx64 ", tmr pool: "
}
uint64_t mul)
{
tmr_hdls_t time;
for (uint32_t i = 0U; i < worker->num_boot_tmr; ++i) {
time = get_time_handles(tmr_pool, tmo_pool, worker->scd.q);
}
}
static int process_periodic(void *args)
{
worker_config_t *worker = args;
prog_config_t *config = worker->prog_config;
stats_t *stats = &worker->stats;
const uint64_t res_ns = prog_conf->opts.res_ns;
int ret;
ODPH_ABORT("Error joining scheduler group, aborting (group: %" PRIu64 ")"
}
boot_periodic(worker, config->tmr_pool, config->tmo_pool, config->per_capa.max_multiplier);
continue;
ODPH_ABORT("Error acking periodic timer, aborting (tmr: %" PRIx64 ")\n",
++stats->num_tmo;
}
while (true) {
config->per_capa.max_multiplier *
WAIT_MULTIPLIER));
break;
if (ret < 0)
ODPH_ABORT("Error acking periodic timer, aborting (tmr: %" PRIx64 ")\n",
if (ret == 1) {
continue;
}
if (ret == 2) {
continue;
}
ODPH_ABORT("Error cancelling periodic timer, aborting "
}
return 0;
}
uint64_t res_ns)
{
tmr_hdls_t time;
for (uint32_t i = 0U; i < worker->num_boot_tmr; ++i) {
time = get_time_handles(tmr_pool, tmo_pool, worker->scd.q);
&worker->stats);
worker->cancel.tmrs[i] = time;
}
}
static int process_cancel(void *args)
{
worker_config_t *worker = args;
prog_config_t *config = worker->prog_config;
const uint64_t res_ns = prog_conf->opts.res_ns;
stats_t *stats = &worker->stats;
const uint32_t num_boot_tmr = worker->num_boot_tmr;
tmr_hdls_t *time;
int ret;
ODPH_ABORT("Error joining scheduler group, aborting (group: %" PRIu64 ")\n",
boot_cancel(worker, tmr_pool, config->tmo_pool, res_ns);
ev, res_ns, stats);
++stats->num_miss;
continue;
}
for (uint32_t i = 0U; i < num_boot_tmr; ++i) {
time = &worker->cancel.tmrs[i];
continue;
ODPH_ABORT("Error cancelling timer, aborting (tmr: %" PRIx64 ")\n",
time->is_running = false;
++stats->num_tmo;
}
for (uint32_t i = 0U; i < num_boot_tmr; ++i) {
time = &worker->cancel.tmrs[i];
if (time->is_running)
continue;
res_ns, stats);
time->is_running = true;
}
}
while (true) {
WAIT_MULTIPLIER));
break;
}
return 0;
}
static odp_bool_t setup_workers(prog_config_t *config)
{
odph_thread_common_param_t thr_common;
odph_thread_param_t thr_params[config->opts.num_workers], *thr_param;
worker_config_t *worker;
const uint32_t mode = config->opts.mode;
int (*start_fn)(void *) = mode == SINGLE_SHOT ? process_single_shot :
mode == PERIODIC ? process_periodic : process_cancel;
odph_thread_common_param_init(&thr_common);
thr_common.instance = config->odp_instance;
thr_common.cpumask = &config->worker_mask;
for (uint32_t i = 0; i < config->opts.num_workers; ++i) {
thr_param = &thr_params[i];
worker = &config->worker_config[i];
odph_thread_param_init(thr_param);
thr_param->start = start_fn;
thr_param->arg = worker;
}
if ((uint32_t)odph_thread_create(config->thread_tbl, &thr_common, thr_params,
config->opts.num_workers) != config->opts.num_workers) {
ODPH_ERR("Error configuring worker threads\n");
return false;
}
return true;
}
static odp_bool_t setup_test(prog_config_t *config)
{
return setup_config(config) && setup_workers(config);
}
static void run_control(prog_config_t *config)
{
const uint32_t time_sec = config->opts.time_sec;
if (time_sec > 0U) {
sleep(time_sec);
} else {
sleep(1U);
}
(void)odph_thread_join(config->thread_tbl, config->opts.num_workers);
}
static void print_humanised(uint64_t value)
{
if (value > GIGAS)
printf("%.2f GOPS\n", (double)value / GIGAS);
else if (value > MEGAS)
printf("%.2f MOPS\n", (double)value / MEGAS);
else if (value > KILOS)
printf("%.2f kOPS\n", (double)value / KILOS);
else
printf("%" PRIu64 " OPS\n", value);
}
static void print_stats(const prog_config_t *config)
{
const stats_t *stats;
const opts_t *opts = &config->opts;
uint64_t tot_tmo = 0U, tot_miss = 0U, tot_retry = 0U, max_mul = 0U, rate, tot_rate = 0U;
printf("=====================\n\n"
"" PROG_NAME " done\n\n"
" mode: %s\n"
" clock source: %d\n"
" resolution: %" PRIu64 " ns\n"
" number of timers: %u (%s)\n\n", opts->mode == SINGLE_SHOT ? "single shot" :
opts->mode == PERIODIC ?
"periodic" : "single shot with cancel",
opts->clk_src, opts->res_ns, opts->num_tmr,
opts->policy == SHARED_TMR ? "shared" : "private");
for (uint32_t i = 0U; i < config->opts.num_workers; ++i) {
stats = &config->worker_config[i].stats;
tot_tmo += stats->num_tmo;
tot_miss += stats->num_miss;
tot_retry += stats->num_retry;
max_mul = ODPH_MAX(max_mul, stats->max_mul);
tot_rate += rate;
printf(" worker %u:\n"
" %s%" PRIu64 "\n", i,
opts->mode == SINGLE_SHOT || opts->mode == PERIODIC ?
"number of timeouts: " : "number of cancels: ",
stats->num_tmo);
if (opts->mode == SINGLE_SHOT || opts->mode == CANCEL) {
if (opts->mode == CANCEL)
printf(" number of misses: %" PRIu64 "\n", stats->num_miss);
printf(" number of retries: %" PRIu64 "\n"
" max start mul: %" PRIu64 "\n", stats->num_retry,
stats->max_mul);
}
printf(" runtime: %" PRIu64 " ns\n"
" rate: ", stats->tot_tm);
print_humanised(rate);
printf("\n");
}
printf(" total:\n"
" %s%" PRIu64 "\n", opts->mode == SINGLE_SHOT || opts->mode == PERIODIC ?
"number of timeouts: " : "number of cancels: ",
tot_tmo);
if (opts->mode == SINGLE_SHOT || opts->mode == CANCEL) {
if (opts->mode == CANCEL)
printf(" number of misses: %" PRIu64 "\n", tot_miss);
printf(" number of retries: %" PRIu64 "\n"
" max start mul: %" PRIu64 "\n", tot_retry, max_mul);
}
printf(" rate: ");
print_humanised(tot_rate);
printf("\n=====================\n");
}
static void teardown(const prog_config_t *config)
{
const opts_t *opts = &config->opts;
const worker_config_t *worker;
for (uint32_t i = 0U; i < opts->num_workers; ++i) {
worker = &config->worker_config[i];
}
}
int main(int argc, char **argv)
{
odph_helper_options_t odph_opts;
int ret = EXIT_SUCCESS;
parse_result_t parse_res;
argc = odph_parse_options(argc, argv);
if (odph_options(&odph_opts) == -1)
ODPH_ABORT("Error while reading ODP helper options, aborting\n");
ODPH_ABORT("ODP global init failed, aborting\n");
ODPH_ABORT("ODP local init failed, aborting\n");
shm_cfg =
odp_shm_reserve(PROG_NAME
"_cfg",
sizeof(prog_config_t), ODP_CACHE_LINE_SIZE,
0U);
ODPH_ERR("Error reserving shared memory\n");
ret = EXIT_FAILURE;
goto out;
}
if (prog_conf == NULL) {
ODPH_ERR("Error resolving shared memory address\n");
ret = EXIT_FAILURE;
goto out;
}
memset(prog_conf, 0, sizeof(*prog_conf));
parse_res = setup_program(argc, argv, prog_conf);
if (parse_res == PRS_NOK) {
ret = EXIT_FAILURE;
goto out;
}
if (parse_res == PRS_TERM) {
ret = EXIT_SUCCESS;
goto out;
}
if (!setup_test(prog_conf)) {
ret = EXIT_FAILURE;
goto out;
}
run_control(prog_conf);
print_stats(prog_conf);
out:
teardown(prog_conf);
ODPH_ABORT("ODP local terminate failed, aborting\n");
ODPH_ABORT("ODP global terminate failed, aborting\n");
return ret;
}
void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
Initialize atomic uint32 variable.
uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable.
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
void odp_barrier_init(odp_barrier_t *barr, int count)
Initialize barrier with thread count.
void odp_barrier_wait(odp_barrier_t *barr)
Synchronize thread execution on barrier.
#define ODP_ALIGNED_CACHE
Defines type/struct/variable to be cache line size aligned.
#define odp_unlikely(x)
Branch unlikely taken.
#define ODP_UNUSED
Intentionally unused variables of functions.
#define ODP_CACHE_LINE_ROUNDUP(x)
Round up to cache line size.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
void odp_event_free(odp_event_t event)
Free event.
#define ODP_EVENT_INVALID
Invalid event.
int odp_instance(odp_instance_t *instance)
Get instance handle.
void odp_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
void odp_spinlock_lock(odp_spinlock_t *splock)
Acquire spin lock.
void odp_spinlock_init(odp_spinlock_t *splock)
Initialize spin lock.
void odp_spinlock_unlock(odp_spinlock_t *splock)
Release spin lock.
uint64_t odp_pool_to_u64(odp_pool_t hdl)
Get printable value for an odp_pool_t.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_TIMEOUT
Timeout pool.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
Queue create.
int odp_queue_destroy(odp_queue_t queue)
Destroy ODP queue.
@ ODP_QUEUE_TYPE_SCHED
Scheduled queue.
int odp_schedule_group_t
Scheduler thread group.
int odp_schedule_group_join(odp_schedule_group_t group, const odp_thrmask_t *mask)
Join a schedule group.
int odp_schedule_group_destroy(odp_schedule_group_t group)
Schedule group destroy.
#define ODP_SCHED_GROUP_INVALID
Invalid scheduler group.
#define ODP_SCHED_NO_WAIT
Do not wait.
int odp_schedule_default_prio(void)
Default scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
uint64_t odp_schedule_group_to_u64(odp_schedule_group_t group)
Get printable value for schedule group handle.
uint64_t odp_schedule_wait_time(uint64_t ns)
Schedule wait time.
odp_schedule_group_t odp_schedule_group_create(const char *name, const odp_thrmask_t *mask)
Schedule group create.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
#define ODP_SHM_INVALID
Invalid shared memory block.
int odp_shm_capability(odp_shm_capability_t *capa)
Query shared memory capabilities.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
double odp_fract_u64_to_dbl(const odp_fract_u64_t *fract)
Convert fractional number (u64) to double.
void odp_thrmask_set(odp_thrmask_t *mask, int thr)
Add thread to mask.
int odp_thread_id(void)
Get thread identifier.
void odp_thrmask_zero(odp_thrmask_t *mask)
Clear entire thread mask.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
odp_time_t odp_time_local_strict(void)
Current local time (strict)
uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
Time difference in nanoseconds.
int odp_timer_pool_start_multi(odp_timer_pool_t timer_pool[], int num)
Start timer pools.
odp_timeout_t odp_timeout_alloc(odp_pool_t pool)
Timeout alloc.
int odp_timer_free(odp_timer_t timer)
Free a timer.
int odp_timer_periodic_start(odp_timer_t timer, const odp_timer_periodic_start_t *start_param)
Start a periodic timer.
odp_timeout_t odp_timeout_from_event(odp_event_t ev)
Get timeout handle from a ODP_EVENT_TIMEOUT type event.
#define ODP_TIMER_POOL_INVALID
Invalid timer pool handle.
int odp_timer_periodic_capability(odp_timer_clk_src_t clk_src, odp_timer_periodic_capability_t *capa)
Periodic timer capability.
odp_timer_pool_t odp_timer_pool_create(const char *name, const odp_timer_pool_param_t *params)
Create a timer pool.
odp_timer_t odp_timeout_timer(odp_timeout_t tmo)
Return timer handle for the timeout.
int odp_timer_cancel(odp_timer_t timer, odp_event_t *tmo_ev)
Cancel a timer.
int odp_timer_capability(odp_timer_clk_src_t clk_src, odp_timer_capability_t *capa)
Query timer capabilities per clock source.
uint64_t odp_timer_ns_to_tick(odp_timer_pool_t timer_pool, uint64_t ns)
Convert nanoseconds to timer ticks.
int odp_timer_periodic_ack(odp_timer_t timer, odp_event_t tmo_ev)
Acknowledge timeout from a periodic timer.
uint64_t odp_timeout_to_u64(odp_timeout_t tmo)
Get printable value for an odp_timeout_t.
odp_timer_clk_src_t
Clock sources for timer pools.
int odp_timer_start(odp_timer_t timer, const odp_timer_start_t *start_param)
Start a timer.
int odp_timer_res_capability(odp_timer_clk_src_t clk_src, odp_timer_res_capability_t *res_capa)
Timer resolution capability.
int odp_timer_periodic_cancel(odp_timer_t timer)
Cancel a periodic timer.
odp_event_t odp_timeout_to_event(odp_timeout_t tmo)
Convert timeout handle to event handle.
#define ODP_TIMEOUT_INVALID
Invalid timeout handle.
odp_timer_t odp_timer_alloc(odp_timer_pool_t timer_pool, odp_queue_t queue, const void *user_ptr)
Allocate a timer.
uint64_t odp_timer_pool_to_u64(odp_timer_pool_t timer_pool)
Get printable value for an odp_timer_pool_t.
#define ODP_TIMER_INVALID
Invalid timer handle.
uint64_t odp_timer_to_u64(odp_timer_t timer)
Get printable value for an odp_timer_t.
void odp_timer_pool_param_init(odp_timer_pool_param_t *param)
Initialize timer pool parameters.
void odp_timer_pool_destroy(odp_timer_pool_t timer_pool)
Destroy a timer pool.
@ ODP_TIMER_SUCCESS
Timer operation succeeded.
@ ODP_TIMER_TOO_NEAR
Timer operation failed, too near to the current time.
@ ODP_TIMER_FAIL
Timer operation failed.
@ ODP_TIMER_TYPE_PERIODIC
Periodic timer.
@ ODP_TIMER_TYPE_SINGLE
Single shot timer.
@ ODP_TIMER_TICK_REL
Relative ticks.
Unsigned 64 bit fractional number.
uint64_t integer
Integer part.
uint64_t denom
Denominator of the fraction part.
uint64_t numer
Numerator of the fraction part.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
uint32_t max_num
Maximum number of buffers of any size.
struct odp_pool_capability_t::@123 tmo
Timeout pool capabilities
uint32_t num
Number of buffers in the pool.
struct odp_pool_param_t::@127 tmo
Parameters for timeout pools.
uint32_t cache_size
Maximum number of buffers cached locally per thread.
odp_pool_type_t type
Pool type.
odp_schedule_param_t sched
Scheduler parameters.
odp_queue_type_t type
Queue type.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
Shared memory capabilities.
uint32_t max_blocks
Maximum number of shared memory blocks.
uint64_t max_size
Maximum memory block size in bytes.
odp_fract_u64_t min_base_freq_hz
Minimum supported base frequency value.
uint32_t max_timers
Maximum number of single shot timers in a pool.
uint32_t max_pools
Maximum number of timer pools for single shot timers (per clock source)
odp_fract_u64_t max_base_freq_hz
Maximum supported base frequency value.
struct odp_timer_capability_t::@156 periodic
Periodic timer capabilities.
uint64_t highest_res_ns
Highest timer resolution in nanoseconds.
odp_bool_t queue_type_sched
Scheduled queue destination support.
Periodic timer capability.
Periodic timer start parameters.
uint64_t res_ns
Timeout resolution in nanoseconds.
odp_timer_type_t timer_type
Timer type.
uint64_t max_multiplier
Maximum base frequency multiplier.
odp_fract_u64_t base_freq_hz
Timer pool base frequency in hertz.
struct odp_timer_pool_param_t::@157 periodic
Periodic timer parameters.
uint64_t min_tmo
Minimum relative timeout in nanoseconds.
uint32_t num_timers
Number of timers in the pool.
odp_timer_clk_src_t clk_src
Clock source for timers.
uint64_t max_tmo
Maximum relative timeout in nanoseconds.
Timer resolution capability.
uint64_t tick
Expiration time in ticks.
odp_event_t tmo_ev
Timeout event.
odp_timer_tick_type_t tick_type
Tick type.