22 #include <odp/helper/odph_api.h>
24 #define MODE_SCHED_OVERH 0
25 #define MODE_START_CANCEL 1
26 #define MODE_START_EXPIRE 2
27 #define MAX_TIMER_POOLS 32
28 #define MAX_TIMERS 10000
29 #define START_NS (100 * ODP_TIME_MSEC_IN_NS)
31 typedef struct test_options_t {
43 typedef struct time_stat_t {
50 typedef struct test_stat_t {
65 typedef struct test_stat_sum_t {
83 typedef struct thread_arg_t {
89 typedef struct timer_ctx_t {
98 typedef struct timer_pool_t {
101 uint64_t period_tick;
105 typedef struct test_global_t {
106 test_options_t test_options;
111 timer_pool_t timer_pool[MAX_TIMER_POOLS];
115 timer_ctx_t timer_ctx[MAX_TIMER_POOLS][MAX_TIMERS];
119 test_stat_sum_t stat_sum;
123 test_global_t *test_global;
125 static void print_usage(
void)
128 "Timer performance test\n"
130 "Usage: odp_timer_perf [options]\n"
132 " -c, --num_cpu Number of CPUs (worker threads). 0: all available CPUs. Default: 1\n"
133 " -n, --num_tp Number of timer pools. Default: 1\n"
134 " -t, --num_timer Number of timers per timer pool. Default: 10\n"
135 " -r, --res_ns Resolution in nsec. Default: 10000000\n"
136 " -p, --period_ns Timeout period in nsec. Default: 100000000\n"
137 " -s, --shared Shared vs private timer pool. Currently, private pools can be\n"
138 " tested only with single CPU. Default: 1\n"
139 " 0: Private timer pools\n"
140 " 1: Shared timer pools\n"
141 " -m, --mode Select test mode. Default: 0\n"
142 " 0: Measure odp_schedule() overhead when using timers\n"
143 " 1: Measure timer set + cancel performance\n"
144 " 2: Measure schedule and timer start overhead while continuously\n"
145 " restarting expiring timers\n"
146 " -R, --rounds Number of test rounds in timer set + cancel test.\n"
148 " -h, --help This help\n"
152 static int parse_options(
int argc,
char *argv[], test_options_t *test_options)
157 static const struct option longopts[] = {
158 {
"num_cpu", required_argument, NULL,
'c'},
159 {
"num_tp ", required_argument, NULL,
'n'},
160 {
"num_timer", required_argument, NULL,
't'},
161 {
"res_ns", required_argument, NULL,
'r'},
162 {
"period_ns", required_argument, NULL,
'p'},
163 {
"shared", required_argument, NULL,
's'},
164 {
"mode", required_argument, NULL,
'm'},
165 {
"rounds", required_argument, NULL,
'R'},
166 {
"help", no_argument, NULL,
'h'},
170 static const char *shortopts =
"+c:n:t:r:p:s:m:R:h";
172 test_options->num_cpu = 1;
173 test_options->num_tp = 1;
174 test_options->num_timer = 10;
177 test_options->shared = 1;
178 test_options->mode = 0;
179 test_options->test_rounds = 100000;
182 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
189 test_options->num_cpu = atoi(optarg);
192 test_options->num_tp = atoi(optarg);
195 test_options->num_timer = atoi(optarg);
198 test_options->res_ns = atoll(optarg);
201 test_options->period_ns = atoll(optarg);
204 test_options->shared = atoi(optarg);
207 test_options->mode = atoi(optarg);
210 test_options->test_rounds = atoll(optarg);
221 if (test_options->num_timer > MAX_TIMERS) {
222 ODPH_ERR(
"Too many timers. Max %u\n", MAX_TIMERS);
229 static int set_num_cpu(test_global_t *global)
232 test_options_t *test_options = &global->test_options;
233 int num_cpu = test_options->num_cpu;
234 int shared = test_options->shared;
244 if (num_cpu && ret != num_cpu) {
245 ODPH_ERR(
"Too many workers. Max supported %i\n.", ret);
249 if (shared == 0 && num_cpu != 1) {
250 ODPH_ERR(
"Private pool test supports only single CPU\n.");
257 test_options->num_cpu = num_cpu;
268 static int create_timer_pools(test_global_t *global)
278 uint64_t max_tmo_ns, min_tmo_ns;
282 test_options_t *test_options = &global->test_options;
283 uint32_t num_cpu = test_options->num_cpu;
284 uint32_t num_tp = test_options->num_tp;
285 uint32_t num_timer = test_options->num_timer;
286 uint64_t res_ns = test_options->res_ns;
287 uint64_t period_ns = test_options->period_ns;
288 int mode = test_options->mode;
289 char tp_name[] =
"timer_pool_00";
291 max_tmo_ns = START_NS + (num_timer * period_ns);
292 min_tmo_ns = START_NS / 2;
294 if (test_options->mode == MODE_START_EXPIRE) {
300 max_tmo_ns = period_ns * 3;
301 min_tmo_ns = test_options->res_ns / 2;
305 if (test_options->shared == 0)
308 printf(
"\nTimer performance test\n");
309 printf(
" mode %i\n", mode);
310 printf(
" num cpu %u\n", num_cpu);
311 printf(
" private pool %i\n", priv);
312 printf(
" num timer pool %u\n", num_tp);
313 printf(
" num timer %u\n", num_timer);
314 printf(
" resolution %" PRIu64
" nsec\n", res_ns);
315 printf(
" period %" PRIu64
" nsec\n", period_ns);
316 printf(
" max timeout %" PRIu64
" nsec\n", max_tmo_ns);
317 printf(
" min timeout %" PRIu64
" nsec\n", min_tmo_ns);
319 if (mode == MODE_SCHED_OVERH)
322 printf(
" test rounds %" PRIu64
"\n", test_options->test_rounds);
324 for (i = 0; i < MAX_TIMER_POOLS; i++) {
329 for (j = 0; j < MAX_TIMERS; j++)
334 ODPH_ERR(
"Timer capability failed\n");
339 timer_res_capa.
res_ns = res_ns;
341 ODPH_ERR(
"Timer resolution capability failed\n");
346 ODPH_ERR(
"Too high resolution\n");
350 if (min_tmo_ns < timer_res_capa.
min_tmo) {
351 ODPH_ERR(
"Too short min timeout\n");
355 if (max_tmo_ns > timer_res_capa.
max_tmo) {
356 ODPH_ERR(
"Too long max timeout\n");
361 if (max_timers && num_timer > max_timers) {
362 ODPH_ERR(
"Too many timers (max %u)\n", max_timers);
367 ODPH_ERR(
"Too many timer pools (max %u)\n", timer_capa.
max_pools);
372 timer_pool_param.
res_ns = res_ns;
373 timer_pool_param.
min_tmo = min_tmo_ns;
374 timer_pool_param.
max_tmo = max_tmo_ns;
376 timer_pool_param.
priv = priv;
381 pool_param.
tmo.
num = num_timer;
389 for (i = 0; i < num_tp; i++) {
391 tp_name[11] =
'0' + i / 10;
392 tp_name[12] =
'0' + i % 10;
396 global->timer_pool[i].tp = tp;
398 ODPH_ERR(
"Timer pool create failed (%u)\n", i);
403 ODPH_ERR(
"Timer pool start failed (%u)\n", i);
408 global->pool[i] = pool;
410 ODPH_ERR(
"Pool create failed (%u)\n", i);
415 global->queue[i] = queue;
417 ODPH_ERR(
"Queue create failed (%u)\n", i);
422 test_options->period_ns);
426 printf(
" start %" PRIu64
" tick\n", global->timer_pool[0].start_tick);
427 printf(
" period %" PRIu64
" ticks\n", global->timer_pool[0].period_tick);
433 static int set_timers(test_global_t *global)
441 uint64_t tick_cur, nsec, time_ns;
444 test_options_t *test_options = &global->test_options;
445 uint32_t num_tp = test_options->num_tp;
446 uint32_t num_timer = test_options->num_timer;
447 uint64_t period_ns = test_options->period_ns;
449 max_tmo_ns = START_NS + (num_timer * period_ns);
451 for (i = 0; i < num_tp; i++) {
452 tp = global->timer_pool[i].tp;
453 pool = global->pool[i];
454 queue = global->queue[i];
461 for (j = 0; j < num_timer; j++) {
466 timer_ctx_t *ctx = &global->timer_ctx[i][j];
473 ctx->target_ns = time_ns + nsec;
481 global->timer[i][j] = timer;
484 nsec = nsec - period_ns;
487 start_param.
tick = tick_cur + tick_ns;
490 if (test_options->mode == MODE_START_EXPIRE) {
491 uint64_t offset_ns = period_ns + j * period_ns / num_timer;
493 ctx->target_ns = time_ns + offset_ns;
495 start_param.
tick = ctx->target_tick;
500 ODPH_ERR(
"Timer set %i/%i (ret %i)\n", i, j, status);
506 ODPH_ERR(
"Timer pool info failed\n");
510 printf(
"Timer pool info [%i]:\n", i);
511 printf(
" cur_timers %u\n", timer_pool_info.
cur_timers);
512 printf(
" hwm_timers %u\n", timer_pool_info.
hwm_timers);
519 static int destroy_timer_pool(test_global_t *global)
526 test_options_t *test_options = &global->test_options;
527 uint32_t num_timer = test_options->num_timer;
528 uint32_t num_tp = test_options->num_tp;
530 for (i = 0; i < num_tp; i++) {
531 for (j = 0; j < num_timer; j++) {
532 timer = global->timer[i][j];
538 printf(
"Timer free failed: %i/%i\n", i, j);
541 queue = global->queue[i];
545 pool = global->pool[i];
549 tp = global->timer_pool[i].tp;
557 static int sched_mode_worker(
void *arg)
563 uint64_t c2, diff, nsec, time_ns, target_ns;
565 time_stat_t before, after;
567 thread_arg_t *thread_arg = arg;
568 test_global_t *global = thread_arg->global;
569 test_options_t *test_options = &global->test_options;
570 uint32_t num_tp = test_options->num_tp;
578 memset(&before, 0,
sizeof(time_stat_t));
579 memset(&after, 0,
sizeof(time_stat_t));
617 target_ns = ctx->target_ns;
618 if (time_ns < target_ns) {
619 diff = target_ns - time_ns;
621 before.sum_ns += diff;
622 if (diff > before.max_ns)
623 before.max_ns = diff;
625 ODPH_DBG(
"before %" PRIu64
"\n", diff);
627 diff = time_ns - target_ns;
629 after.sum_ns += diff;
630 if (diff > after.max_ns)
633 ODPH_DBG(
"after %" PRIu64
"\n", time_ns - target_ns);
644 global->stat[thr].events = events;
645 global->stat[thr].cycles_0 = cycles;
646 global->stat[thr].rounds = rounds;
647 global->stat[thr].nsec = nsec;
648 global->stat[thr].before = before;
649 global->stat[thr].after = after;
654 static int cancel_timers(test_global_t *global, uint32_t worker_idx)
660 test_options_t *test_options = &global->test_options;
661 uint32_t num_tp = test_options->num_tp;
662 uint32_t num_timer = test_options->num_timer;
663 uint32_t num_worker = test_options->num_cpu;
666 for (i = 0; i < num_tp; i++) {
667 for (j = worker_idx; j < num_timer; j += num_worker) {
668 timer = global->timer[i][j];
688 static int set_cancel_mode_worker(
void *arg)
690 uint64_t tick, start_tick, period_tick, nsec;
693 uint32_t i, j, worker_idx;
700 thread_arg_t *thread_arg = arg;
701 test_global_t *global = thread_arg->global;
702 test_options_t *test_options = &global->test_options;
703 uint32_t num_tp = test_options->num_tp;
704 uint32_t num_timer = test_options->num_timer;
705 uint32_t num_worker = test_options->num_cpu;
708 uint64_t test_rounds = test_options->test_rounds;
709 uint64_t num_tmo = 0;
710 uint64_t num_cancel = 0;
711 uint64_t num_set = 0;
712 uint64_t cancel_cycles = 0, start_cycles = 0;
716 worker_idx = thread_arg->worker_idx;
734 timer = global->timer[i][j];
735 start_tick = global->timer_pool[i].start_tick;
736 period_tick = global->timer_pool[i].period_tick;
737 tick = start_tick + j * period_tick;
740 start_param.
tick = tick;
748 ODPH_ERR(
"Timer set (tmo) failed (ret %i)\n", status);
770 for (i = 0; i < num_tp; i++) {
771 tp = global->timer_pool[i].tp;
775 start_tick = global->timer_pool[i].start_tick;
776 period_tick = global->timer_pool[i].period_tick;
781 for (j = worker_idx; j < num_timer; j += num_worker) {
784 timer = global->timer[i][j];
794 ODPH_ERR(
"Timer (%u/%u) cancel failed (ret %i)\n", i, j,
805 for (j = worker_idx; j < num_timer; j += num_worker) {
809 timer = global->timer[i][j];
814 start_param.
tick = tick + j * period_tick;
815 start_param.
tmo_ev = ev_tbl[j];
821 ODPH_ERR(
"Timer (%u/%u) set failed (ret %i)\n", i, j,
834 if (test_rounds == 0)
843 if (cancel_timers(global, worker_idx))
844 ODPH_ERR(
"Timer cancel failed\n");
847 global->stat[thr].events = num_tmo;
848 global->stat[thr].rounds = test_options->test_rounds - test_rounds;
849 global->stat[thr].nsec = nsec;
850 global->stat[thr].cycles_0 = cancel_cycles;
851 global->stat[thr].cycles_1 = start_cycles;
853 global->stat[thr].cancels = num_cancel;
854 global->stat[thr].sets = num_set;
859 static int set_expire_mode_worker(
void *arg)
862 uint32_t i, j, exit_test;
865 uint64_t c2, c3, c4, diff, nsec, time_ns, target_ns, period_tick, wait;
869 time_stat_t before, after;
871 thread_arg_t *thread_arg = arg;
872 test_global_t *global = thread_arg->global;
873 test_options_t *opt = &global->test_options;
874 uint32_t num_tp = opt->num_tp;
875 uint64_t sched_cycles = 0;
876 uint64_t start_cycles = 0;
883 memset(&before, 0,
sizeof(time_stat_t));
884 memset(&after, 0,
sizeof(time_stat_t));
893 while (events < opt->test_rounds * opt->num_timer / opt->num_cpu) {
908 sched_cycles += diff;
919 timer = global->timer[i][j];
920 period_tick = global->timer_pool[i].period_tick;
922 target_ns = ctx->target_ns;
924 if (time_ns < target_ns) {
925 diff = target_ns - time_ns;
927 before.sum_ns += diff;
928 if (diff > before.max_ns)
929 before.max_ns = diff;
931 ODPH_DBG(
"before %" PRIu64
"\n", diff);
933 diff = time_ns - target_ns;
935 after.sum_ns += diff;
936 if (diff > after.max_ns)
939 ODPH_DBG(
"after %" PRIu64
"\n", diff);
944 ctx->target_ns += opt->period_ns;
945 ctx->target_tick += period_tick;
946 start_param.
tick = ctx->target_tick;
954 start_cycles += diff;
957 ODPH_ERR(
"Timer set (tmo) failed (ret %i)\n", status);
967 status = cancel_timers(global, thread_arg->worker_idx);
982 global->stat[thr].events = events;
983 global->stat[thr].cycles_0 = sched_cycles;
984 global->stat[thr].cycles_1 = start_cycles;
985 global->stat[thr].rounds = rounds;
986 global->stat[thr].nsec = nsec;
987 global->stat[thr].before = before;
988 global->stat[thr].after = after;
993 static int start_workers(test_global_t *global,
odp_instance_t instance)
995 odph_thread_common_param_t thr_common;
997 test_options_t *test_options = &global->test_options;
998 int num_cpu = test_options->num_cpu;
999 odph_thread_param_t thr_param[num_cpu];
1001 memset(global->thread_tbl, 0,
sizeof(global->thread_tbl));
1002 odph_thread_common_param_init(&thr_common);
1004 thr_common.instance = instance;
1005 thr_common.cpumask = &global->cpumask;
1007 for (i = 0; i < num_cpu; i++) {
1008 odph_thread_param_init(&thr_param[i]);
1010 if (test_options->mode == MODE_SCHED_OVERH)
1011 thr_param[i].start = sched_mode_worker;
1012 else if (test_options->mode == MODE_START_CANCEL)
1013 thr_param[i].start = set_cancel_mode_worker;
1015 thr_param[i].start = set_expire_mode_worker;
1017 thr_param[i].arg = &global->thread_arg[i];
1021 ret = odph_thread_create(global->thread_tbl, &thr_common, thr_param,
1024 if (ret != num_cpu) {
1025 ODPH_ERR(
"Thread create failed %i\n", ret);
1032 static void sum_stat(test_global_t *global)
1035 test_stat_sum_t *sum = &global->stat_sum;
1037 memset(sum, 0,
sizeof(test_stat_sum_t));
1040 if (global->stat[i].rounds == 0)
1044 sum->events += global->stat[i].events;
1045 sum->rounds += global->stat[i].rounds;
1046 sum->cycles_0 += global->stat[i].cycles_0;
1047 sum->cycles_1 += global->stat[i].cycles_1;
1048 sum->nsec += global->stat[i].nsec;
1049 sum->cancels += global->stat[i].cancels;
1050 sum->sets += global->stat[i].sets;
1052 sum->before.num += global->stat[i].before.num;
1053 sum->before.sum_ns += global->stat[i].before.sum_ns;
1054 sum->after.num += global->stat[i].after.num;
1055 sum->after.sum_ns += global->stat[i].after.sum_ns;
1057 if (global->stat[i].before.max_ns > sum->before.max_ns)
1058 sum->before.max_ns = global->stat[i].before.max_ns;
1060 if (global->stat[i].after.max_ns > sum->after.max_ns)
1061 sum->after.max_ns = global->stat[i].after.max_ns;
1068 static void print_stat_sched_mode(test_global_t *global)
1071 test_stat_sum_t *sum = &global->stat_sum;
1072 double round_ave = 0.0;
1073 double before_ave = 0.0;
1074 double after_ave = 0.0;
1078 printf(
"RESULTS - schedule() cycles per thread:\n");
1079 printf(
"----------------------------------------------\n");
1080 printf(
" 1 2 3 4 5 6 7 8 9 10");
1083 if (global->stat[i].rounds) {
1084 if ((num % 10) == 0)
1087 printf(
"%6.1f ", (
double)global->stat[i].cycles_0 / global->stat[i].rounds);
1095 round_ave = (double)sum->rounds / sum->num;
1097 if (sum->before.num)
1098 before_ave = (double)sum->before.sum_ns / sum->before.num;
1101 after_ave = (double)sum->after.sum_ns / sum->after.num;
1103 printf(
"TOTAL (%i workers)\n", sum->num);
1104 printf(
" events: %" PRIu64
"\n", sum->events);
1105 printf(
" ave time: %.2f sec\n", sum->time_ave);
1106 printf(
" ave rounds per sec: %.2fM\n", (round_ave / sum->time_ave) / 1000000.0);
1107 printf(
" num before: %" PRIu64
"\n", sum->before.num);
1108 printf(
" ave before: %.1f nsec\n", before_ave);
1109 printf(
" max before: %" PRIu64
" nsec\n", sum->before.max_ns);
1110 printf(
" num after: %" PRIu64
"\n", sum->after.num);
1111 printf(
" ave after: %.1f nsec\n", after_ave);
1112 printf(
" max after: %" PRIu64
" nsec\n", sum->after.max_ns);
1116 static void print_stat_set_cancel_mode(test_global_t *global)
1119 test_stat_sum_t *sum = &global->stat_sum;
1120 double set_ave = 0.0;
1124 printf(
"RESULTS\n");
1125 printf(
"odp_timer_cancel() cycles per thread:\n");
1126 printf(
"-------------------------------------------------\n");
1127 printf(
" 1 2 3 4 5 6 7 8 9 10");
1130 const test_stat_t *si = &global->stat[i];
1133 if ((num % 10) == 0)
1136 printf(
"%6.1f ", (
double)si->cycles_0 / si->cancels);
1144 printf(
"odp_timer_start() cycles per thread:\n");
1145 printf(
"-------------------------------------------------\n");
1146 printf(
" 1 2 3 4 5 6 7 8 9 10");
1149 const test_stat_t *si = &global->stat[i];
1152 if ((num % 10) == 0)
1155 printf(
"%6.1f ", (
double)si->cycles_1 / si->sets);
1161 set_ave = (double)sum->sets / sum->num;
1164 printf(
"TOTAL (%i workers)\n", sum->num);
1165 printf(
" rounds: %" PRIu64
"\n", sum->rounds);
1166 printf(
" timeouts: %" PRIu64
"\n", sum->events);
1167 printf(
" timer cancels: %" PRIu64
"\n", sum->cancels);
1168 printf(
" cancels failed: %" PRIu64
"\n", sum->cancels - sum->sets);
1169 printf(
" timer sets: %" PRIu64
"\n", sum->sets);
1170 printf(
" ave time: %.2f sec\n", sum->time_ave);
1171 printf(
" cancel+set per cpu: %.2fM per sec\n", (set_ave / sum->time_ave) / 1000000.0);
1175 static void print_stat_expire_mode(test_global_t *global)
1178 test_stat_sum_t *sum = &global->stat_sum;
1179 double round_ave = 0.0;
1180 double before_ave = 0.0;
1181 double after_ave = 0.0;
1185 printf(
"RESULTS\n");
1186 printf(
"odp_schedule() cycles per thread:\n");
1187 printf(
"-------------------------------------------------\n");
1188 printf(
" 1 2 3 4 5 6 7 8 9 10");
1191 if (global->stat[i].rounds) {
1192 if ((num % 10) == 0)
1195 printf(
"%6.1f ", (
double)global->stat[i].cycles_0 / global->stat[i].rounds);
1203 printf(
"odp_timer_start() cycles per thread:\n");
1204 printf(
"-------------------------------------------------\n");
1205 printf(
" 1 2 3 4 5 6 7 8 9 10");
1208 if (global->stat[i].events) {
1209 if ((num % 10) == 0)
1212 printf(
"%6.1f ", (
double)global->stat[i].cycles_1 / global->stat[i].events);
1220 round_ave = (double)sum->rounds / sum->num;
1222 if (sum->before.num)
1223 before_ave = (double)sum->before.sum_ns / sum->before.num;
1226 after_ave = (double)sum->after.sum_ns / sum->after.num;
1228 printf(
"TOTAL (%i workers)\n", sum->num);
1229 printf(
" events: %" PRIu64
"\n", sum->events);
1230 printf(
" ave time: %.2f sec\n", sum->time_ave);
1231 printf(
" ave rounds per sec: %.2fM\n", (round_ave / sum->time_ave) / 1000000.0);
1232 printf(
" num before: %" PRIu64
"\n", sum->before.num);
1233 printf(
" ave before: %.1f nsec\n", before_ave);
1234 printf(
" max before: %" PRIu64
" nsec\n", sum->before.max_ns);
1235 printf(
" num after: %" PRIu64
"\n", sum->after.num);
1236 printf(
" ave after: %.1f nsec\n", after_ave);
1237 printf(
" max after: %" PRIu64
" nsec\n", sum->after.max_ns);
1241 static void sig_handler(
int signo)
1245 if (test_global == NULL)
1250 int main(
int argc,
char **argv)
1252 odph_helper_options_t helper_options;
1256 test_global_t *global;
1257 test_options_t *test_options;
1258 int i, shared, mode;
1260 signal(SIGINT, sig_handler);
1263 argc = odph_parse_options(argc, argv);
1264 if (odph_options(&helper_options)) {
1265 ODPH_ERR(
"Reading ODP helper options failed.\n");
1277 init.
mem_model = helper_options.mem_model;
1281 ODPH_ERR(
"Global init failed.\n");
1287 ODPH_ERR(
"Local init failed.\n");
1291 shm =
odp_shm_reserve(
"timer_perf_global",
sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0);
1293 ODPH_ERR(
"Shared mem reserve failed.\n");
1298 if (global == NULL) {
1299 ODPH_ERR(
"Shared mem alloc failed\n");
1302 test_global = global;
1304 memset(global, 0,
sizeof(test_global_t));
1309 global->thread_arg[i].global = global;
1310 global->thread_arg[i].worker_idx = i;
1313 if (parse_options(argc, argv, &global->test_options))
1316 test_options = &global->test_options;
1317 shared = test_options->shared;
1318 mode = test_options->mode;
1324 if (set_num_cpu(global))
1327 if (create_timer_pools(global))
1332 start_workers(global, instance);
1343 if (set_timers(global))
1350 if (mode == MODE_SCHED_OVERH) {
1351 if (sched_mode_worker(&global->thread_arg[0])) {
1352 ODPH_ERR(
"Sched_mode_worker failed\n");
1355 }
else if (mode == MODE_START_CANCEL) {
1356 if (set_cancel_mode_worker(&global->thread_arg[0])) {
1357 ODPH_ERR(
"Set_cancel_mode_worker failed\n");
1361 if (set_expire_mode_worker(&global->thread_arg[0])) {
1362 ODPH_ERR(
"Set_expire_mode_worker failed\n");
1368 odph_thread_join(global->thread_tbl,
1369 global->test_options.num_cpu);
1374 if (mode == MODE_SCHED_OVERH)
1375 print_stat_sched_mode(global);
1376 else if (mode == MODE_START_CANCEL)
1377 print_stat_set_cancel_mode(global);
1379 print_stat_expire_mode(global);
1381 destroy_timer_pool(global);
1384 ODPH_ERR(
"Shared mem free failed.\n");
1389 ODPH_ERR(
"Term local failed.\n");
1394 ODPH_ERR(
"Term global failed.\n");
void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
Initialize atomic uint32 variable.
void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val)
Add to atomic uint32 variable.
uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable.
void odp_atomic_inc_u32(odp_atomic_u32_t *atom)
Increment atomic uint32 variable.
uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable using ACQUIRE memory ordering.
void odp_atomic_store_rel_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable using RELEASE memory ordering.
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_unlikely(x)
Branch unlikely taken.
#define odp_likely(x)
Branch likely taken.
uint64_t odp_cpu_cycles_diff(uint64_t c2, uint64_t c1)
CPU cycle count difference.
uint64_t odp_cpu_cycles(void)
Current CPU cycle count.
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.
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.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
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.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
#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_wait_time(uint64_t ns)
Schedule wait time.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
#define ODP_SHM_INVALID
Invalid shared memory block.
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.
void odp_sys_info_print(void)
Print system info.
#define ODP_THREAD_COUNT_MAX
Maximum number of threads supported in build time.
int odp_thread_id(void)
Get thread identifier.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
void odp_time_wait_ns(uint64_t ns)
Wait the specified number of nanoseconds.
odp_time_t odp_time_global(void)
Current global time.
odp_time_t odp_time_local(void)
Current local time.
#define ODP_TIME_NULL
Zero time stamp.
#define ODP_TIME_MSEC_IN_NS
A millisecond in nanoseconds.
uint64_t odp_time_global_ns(void)
Current global time in nanoseconds.
uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
Time difference in nanoseconds.
void odp_timeout_free(odp_timeout_t tmo)
Timeout free.
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.
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.
odp_timer_pool_t odp_timer_pool_create(const char *name, const odp_timer_pool_param_t *params)
Create a timer pool.
int odp_timer_cancel(odp_timer_t timer, odp_event_t *tmo_ev)
Cancel a timer.
uint64_t odp_timer_current_tick(odp_timer_pool_t timer_pool)
Current tick value.
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_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.
odp_event_t odp_timeout_to_event(odp_timeout_t tmo)
Convert timeout handle to event handle.
int odp_timer_pool_info(odp_timer_pool_t timer_pool, odp_timer_pool_info_t *info)
Query timer pool configuration and current state.
odp_timer_t odp_timer_alloc(odp_timer_pool_t timer_pool, odp_queue_t queue, const void *user_ptr)
Allocate a timer.
#define ODP_CLOCK_DEFAULT
The default clock source.
#define ODP_TIMER_INVALID
Invalid timer handle.
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.
void * odp_timeout_user_ptr(odp_timeout_t tmo)
Return user pointer for the timeout.
@ ODP_TIMER_SUCCESS
Timer operation succeeded.
@ ODP_TIMER_TOO_NEAR
Timer operation failed, too near to the current time.
@ ODP_TIMER_TICK_REL
Relative ticks.
@ ODP_TIMER_TICK_ABS
Absolute ticks.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
odp_feature_t not_used
Unused features.
uint32_t num
Number of buffers in the pool.
struct odp_pool_param_t::@127 tmo
Parameters for timeout pools.
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.
odp_schedule_sync_t sync
Synchronization method.
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_timer_res_capability_t max_res
Maximum resolution.
ODP timer pool information and configuration.
uint32_t hwm_timers
High watermark of allocated timers.
uint32_t cur_timers
Number of currently allocated timers.
uint64_t res_ns
Timeout resolution in nanoseconds.
int priv
Thread private timer pool.
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 max_tmo
Maximum relative timeout in nanoseconds.
uint64_t min_tmo
Minimum relative timeout in nanoseconds.
uint64_t res_ns
Timeout resolution in nanoseconds.
uint64_t tick
Expiration time in ticks.
odp_event_t tmo_ev
Timeout event.
odp_timer_tick_type_t tick_type
Tick type.
uint32_t tm
Traffic Manager APIs, e.g., odp_tm_xxx()
uint32_t crypto
Crypto APIs, e.g., odp_crypto_xxx()
uint32_t ipsec
IPsec APIs, e.g., odp_ipsec_xxx()
uint32_t cls
Classifier APIs, e.g., odp_cls_xxx(), odp_cos_xxx()
struct odp_feature_t::@148 feat
Individual feature bits.
uint32_t compress
Compression APIs, e.g., odp_comp_xxx()