22 #include <odp/helper/odph_api.h>
25 #include <export_results.h>
30 #define MAX_QUEUES 4096
32 #define EVENT_POOL_SIZE (1024 * 1024)
35 #define CACHE_ALIGN_ROUNDUP(x)\
36 ((ODP_CACHE_LINE_SIZE) * \
37 (((x) + ODP_CACHE_LINE_SIZE - 1) / (ODP_CACHE_LINE_SIZE)))
45 #define EVENT_FORWARD_RAND 0
46 #define EVENT_FORWARD_INC 1
47 #define EVENT_FORWARD_NONE 2
61 int src_idx[NUM_PRIOS];
68 unsigned int cpu_count;
89 uint64_t sample_events;
98 test_stat_t prio[NUM_PRIOS];
109 test_common_options_t common_options;
120 static void clear_sched_queues(test_globals_t *globals)
131 ODPH_ABORT(
"Buffer alloc failed.\n");
134 event->type = COOL_DOWN;
137 for (i = 0; i < NUM_PRIOS; i++) {
138 for (j = 0; j < globals->args.prio[i].queues; j++) {
141 ODPH_ABORT(
"Queue enqueue failed.\n");
149 if (event->type == COOL_DOWN)
162 ODPH_ABORT(
"Queue %" PRIu64
" not empty.\n",
180 static int enqueue_events(
int prio,
int num_queues,
int num_events,
182 test_globals_t *globals)
190 int events_per_queue;
194 tot_events = num_events + num_samples;
196 if (!num_queues || !tot_events)
199 events_per_queue = tot_events;
201 events_per_queue = (tot_events + num_queues - 1) / num_queues;
203 for (i = 0; i < num_queues; i++) {
204 queue = globals->queue[prio][i];
208 if (ret != events_per_queue) {
209 ODPH_ERR(
"Buffer alloc failed. Try increasing EVENT_POOL_SIZE.\n");
210 ret = ret < 0 ? 0 : ret;
214 for (j = 0; j < events_per_queue; j++) {
216 ODPH_ERR(
"Buffer alloc failed\n");
222 memset(event, 0,
sizeof(test_event_t));
226 if (num_samples > 0) {
227 event->type = WARM_UP;
228 event->warm_up_rounds = 0;
231 event->type = TRAFFIC;
233 event->src_idx[prio] = i;
244 ODPH_ERR(
"Queue enqueue failed.\n");
248 }
while (enq_events < events_per_queue);
250 rdy_events += events_per_queue;
251 if (div_events && rdy_events >= tot_events)
262 static int output_results(test_globals_t *globals)
271 args = &globals->args;
272 stype = globals->args.sync_type;
274 printf(
"\n%s queue scheduling latency\n",
278 printf(
" Forwarding mode: %s\n",
279 (args->forward_mode == EVENT_FORWARD_RAND) ?
"random" :
280 ((args->forward_mode == EVENT_FORWARD_INC) ?
"incremental" :
283 printf(
" LO_PRIO queues: %i\n", args->prio[LO_PRIO].queues);
284 if (args->prio[LO_PRIO].events_per_queue)
285 printf(
" LO_PRIO event per queue: %i\n",
286 args->prio[LO_PRIO].events);
288 printf(
" LO_PRIO events: %i\n", args->prio[LO_PRIO].events);
290 printf(
" LO_PRIO sample events: %i\n", args->prio[LO_PRIO].sample_events);
292 printf(
" HI_PRIO queues: %i\n", args->prio[HI_PRIO].queues);
293 if (args->prio[HI_PRIO].events_per_queue)
294 printf(
" HI_PRIO event per queue: %i\n\n",
295 args->prio[HI_PRIO].events);
297 printf(
" HI_PRIO events: %i\n", args->prio[HI_PRIO].events);
299 printf(
" HI_PRIO sample events: %i\n\n", args->prio[HI_PRIO].sample_events);
301 if (globals->common_options.is_export) {
302 if (test_common_write(
"high priority Avg (ns),high priority Min (ns),"
303 "high priority Max (ns),low priority Avg (ns),"
304 "low priority Min (ns),low priority Max (ns)\n")) {
305 ODPH_ERR(
"Export failed\n");
306 test_common_write_term();
311 for (i = 0; i < NUM_PRIOS; i++) {
312 memset(&total, 0,
sizeof(test_stat_t));
313 total.min = UINT64_MAX;
315 printf(
"%s priority\n"
316 "Thread Avg[ns] Min[ns] Max[ns] Samples Total Max idx\n"
317 "-----------------------------------------------------------------------\n",
318 i == HI_PRIO ?
"HIGH" :
"LOW");
319 for (j = 1; j <= args->cpu_count; j++) {
320 lat = &globals->core_stat[j].prio[i];
322 if (lat->sample_events == 0) {
323 printf(
"%-8d N/A\n", j);
327 if (lat->max > total.max)
328 total.max = lat->max;
329 if (lat->min < total.min)
330 total.min = lat->min;
331 total.tot += lat->tot;
332 total.sample_events += lat->sample_events;
333 total.events += lat->events;
335 avg = lat->events ? lat->tot / lat->sample_events : 0;
336 printf(
"%-8d %-10" PRIu64
" %-10" PRIu64
" "
337 "%-10" PRIu64
" %-10" PRIu64
" %-10" PRIu64
" %-10" PRIu64
"\n",
338 j, avg, lat->min, lat->max, lat->sample_events,
339 lat->events, lat->max_idx);
341 printf(
"-----------------------------------------------------------------------\n");
342 if (total.sample_events == 0) {
343 printf(
"Total N/A\n\n");
346 avg = total.events ? total.tot / total.sample_events : 0;
347 printf(
"Total %-10" PRIu64
" %-10" PRIu64
" %-10" PRIu64
" "
348 "%-10" PRIu64
" %-10" PRIu64
"\n\n", avg, total.min,
349 total.max, total.sample_events, total.events);
351 if (globals->common_options.is_export) {
352 if (test_common_write(
"%" PRIu64
",%" PRIu64
",%" PRIu64
"%s",
353 avg, total.min, total.max, i == 0 ?
"," :
"")) {
354 ODPH_ERR(
"Export failed\n");
355 test_common_write_term();
361 if (globals->common_options.is_export)
362 test_common_write_term();
367 static int join_groups(test_globals_t *globals,
int thr)
372 int num_group = globals->args.num_group;
378 if (globals->args.isolate)
384 for (i = 0; i < num; i++) {
385 if (globals->args.isolate)
386 group = globals->group[i % 2][i / 2];
388 group = globals->group[0][i];
391 ODPH_ERR(
"Group join failed %i (thr %i)\n", i, thr);
416 static int test_schedule(
int thr, test_globals_t *globals)
426 int dst_idx, change_queue;
427 int warm_up_rounds = globals->args.warm_up_rounds;
428 uint64_t test_rounds = globals->args.test_rounds * (uint64_t)1000000;
430 memset(&globals->core_stat[thr], 0,
sizeof(core_stat_t));
431 globals->core_stat[thr].prio[HI_PRIO].min = UINT64_MAX;
432 globals->core_stat[thr].prio[LO_PRIO].min = UINT64_MAX;
434 change_queue = globals->args.forward_mode != EVENT_FORWARD_NONE ? 1 : 0;
438 for (i = 0; i < test_rounds; i++) {
446 stats = &globals->core_stat[thr].prio[
event->prio];
448 if (event->type == SAMPLE) {
451 if (latency > stats->max) {
452 stats->max = latency;
453 stats->max_idx = stats->sample_events;
455 if (latency < stats->min)
456 stats->min = latency;
457 stats->tot += latency;
458 stats->sample_events++;
461 if (!globals->args.sample_per_prio &&
462 globals->args.prio[!event->prio].queues)
463 event->prio = !
event->prio;
467 event->warm_up_rounds++;
468 if (event->warm_up_rounds >= warm_up_rounds)
469 event->type = SAMPLE;
476 dst_idx =
event->src_idx[
event->prio] + 1;
478 dst_idx =
event->src_idx[
event->prio];
479 if (dst_idx >= globals->args.prio[event->prio].queues)
481 event->src_idx[
event->prio] = dst_idx;
482 dst_queue = globals->queue[
event->prio][dst_idx];
484 if (event->type == SAMPLE)
488 ODPH_ERR(
"[%i] Queue enqueue failed.\n", thr);
506 ODPH_ERR(
"[%i] Queue enqueue failed.\n", thr);
514 if (thr == MAIN_THREAD) {
516 clear_sched_queues(globals);
517 if (output_results(globals))
535 test_globals_t *globals;
544 if (globals == NULL) {
545 ODPH_ERR(
"Shared mem lookup failed\n");
549 if (join_groups(globals, thr))
552 if (thr == MAIN_THREAD) {
553 args = &globals->args;
555 if (enqueue_events(HI_PRIO, args->prio[HI_PRIO].queues,
556 args->prio[HI_PRIO].events, args->prio[HI_PRIO].sample_events,
557 !args->prio[HI_PRIO].events_per_queue,
561 if (enqueue_events(LO_PRIO, args->prio[LO_PRIO].queues,
562 args->prio[LO_PRIO].events, args->prio[LO_PRIO].sample_events,
563 !args->prio[LO_PRIO].events_per_queue,
568 if (test_schedule(thr, globals))
577 static void usage(
void)
580 "OpenDataPlane scheduler latency benchmark application.\n"
582 "Usage: ./odp_sched_latency [options]\n"
583 "Optional OPTIONS:\n"
584 " -c, --count <number> CPU count, 0=all available, default=1\n"
585 " -d, --duration <number> Test duration in scheduling rounds (millions), default=10, min=1\n"
586 " -f, --forward-mode <mode> Selection of target queue\n"
587 " 0: Random (default)\n"
589 " 2: Use source queue\n"
590 " -g, --num_group <num> Number of schedule groups. Round robins queues into groups.\n"
591 " -1: SCHED_GROUP_WORKER\n"
592 " 0: SCHED_GROUP_ALL (default)\n"
593 " -i, --isolate <mode> Select if shared or isolated groups are used. Ignored when num_group <= 0.\n"
594 " 0: All queues share groups (default)\n"
595 " 1: Separate groups for high and low priority queues. Creates 2xnum_group groups.\n"
596 " -l, --lo-prio-queues <number> Number of low priority scheduled queues (default=64)\n"
597 " -t, --hi-prio-queues <number> Number of high priority scheduled queues (default=16)\n"
598 " -m, --lo-prio-events-per-queue <number> Number of events per low priority queue (default=32).\n"
599 " Does not include sample event.\n"
600 " -n, --hi-prio-events-per-queue <number> Number of events per high priority queues (default=0)\n"
601 " Does not include sample event.\n"
602 " -o, --lo-prio-events <number> Total number of low priority events. Overrides the\n"
603 " number of events per queue, does not include sample event.\n"
604 " -p, --hi-prio-events <number> Total number of high priority events. Overrides the\n"
605 " number of events per queue, does not include sample event.\n"
606 " -r --sample-per-prio Allocate a separate sample event for each priority. By default\n"
607 " a single sample event is used and its priority is changed after\n"
608 " each processing round.\n"
609 " -s, --sync Scheduled queues' sync type\n"
610 " 0: ODP_SCHED_SYNC_PARALLEL (default)\n"
611 " 1: ODP_SCHED_SYNC_ATOMIC\n"
612 " 2: ODP_SCHED_SYNC_ORDERED\n"
613 " -w, --warm-up <number> Number of warm-up rounds, default=100, min=1\n"
614 " -h, --help Display help and exit.\n\n");
624 static void parse_args(
int argc,
char *argv[], test_args_t *args)
629 static const struct option longopts[] = {
630 {
"count", required_argument, NULL,
'c'},
631 {
"duration", required_argument, NULL,
'd'},
632 {
"forward-mode", required_argument, NULL,
'f'},
633 {
"num_group", required_argument, NULL,
'g'},
634 {
"isolate", required_argument, NULL,
'i'},
635 {
"lo-prio-queues", required_argument, NULL,
'l'},
636 {
"hi-prio-queues", required_argument, NULL,
't'},
637 {
"lo-prio-events-per-queue", required_argument, NULL,
'm'},
638 {
"hi-prio-events-per-queue", required_argument, NULL,
'n'},
639 {
"lo-prio-events", required_argument, NULL,
'o'},
640 {
"hi-prio-events", required_argument, NULL,
'p'},
641 {
"sync", required_argument, NULL,
's'},
642 {
"warm-up", required_argument, NULL,
'w'},
643 {
"sample-per-prio", no_argument, NULL,
'r'},
644 {
"help", no_argument, NULL,
'h'},
648 static const char *shortopts =
"+c:d:f:g:i:l:t:m:n:o:p:s:w:rh";
651 args->forward_mode = EVENT_FORWARD_RAND;
654 args->test_rounds = 10;
655 args->warm_up_rounds = 100;
657 args->sample_per_prio = 0;
658 args->prio[LO_PRIO].queues = 64;
659 args->prio[HI_PRIO].queues = 16;
660 args->prio[LO_PRIO].events = 32;
661 args->prio[HI_PRIO].events = 0;
662 args->prio[LO_PRIO].events_per_queue = 1;
663 args->prio[HI_PRIO].events_per_queue = 0;
664 args->prio[LO_PRIO].sample_events = 0;
665 args->prio[HI_PRIO].sample_events = 1;
668 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
675 args->cpu_count = atoi(optarg);
678 args->test_rounds = atoi(optarg);
681 args->forward_mode = atoi(optarg);
684 args->num_group = atoi(optarg);
687 args->isolate = atoi(optarg);
690 args->prio[LO_PRIO].queues = atoi(optarg);
693 args->prio[HI_PRIO].queues = atoi(optarg);
696 args->prio[LO_PRIO].events = atoi(optarg);
697 args->prio[LO_PRIO].events_per_queue = 1;
700 args->prio[HI_PRIO].events = atoi(optarg);
701 args->prio[HI_PRIO].events_per_queue = 1;
704 args->prio[LO_PRIO].events = atoi(optarg);
705 args->prio[LO_PRIO].events_per_queue = 0;
708 args->prio[HI_PRIO].events = atoi(optarg);
709 args->prio[HI_PRIO].events_per_queue = 0;
721 args->sample_per_prio = 1;
724 args->warm_up_rounds = atoi(optarg);
740 if (args->prio[LO_PRIO].queues > MAX_QUEUES)
741 args->prio[LO_PRIO].queues = MAX_QUEUES;
742 if (args->prio[HI_PRIO].queues > MAX_QUEUES)
743 args->prio[HI_PRIO].queues = MAX_QUEUES;
744 if (args->test_rounds < 1)
745 args->test_rounds = 1;
746 if (!args->prio[HI_PRIO].queues && !args->prio[LO_PRIO].queues) {
747 printf(
"No queues configured\n");
751 if (args->forward_mode > EVENT_FORWARD_NONE ||
752 args->forward_mode < EVENT_FORWARD_RAND) {
753 printf(
"Invalid forwarding mode\n");
758 if (args->num_group > MAX_GROUPS) {
759 ODPH_ERR(
"Too many groups. Max supported %i.\n", MAX_GROUPS);
763 if (args->prio[HI_PRIO].queues == 0 || args->sample_per_prio)
764 args->prio[LO_PRIO].sample_events = 1;
767 static void randomize_queues(
odp_queue_t queues[], uint32_t num, uint64_t *seed)
771 for (i = 0; i < num; i++) {
778 new_index = new_index % num;
779 swap_queue = queues[new_index];
781 queues[new_index] = cur_queue;
782 queues[i] = swap_queue;
796 ODPH_ERR(
"Schedule capability failed\n");
802 printf(
"Too many schedule groups %i (max %u)\n", num, max);
806 for (i = 0; i < NUM_PRIOS; i++)
807 for (j = 0; j < MAX_GROUPS; j++)
812 for (i = 0; i < num; i++) {
816 ODPH_ERR(
"Group create failed %i\n", i);
820 if (globals->args.isolate) {
821 globals->group[i % 2][i / 2] = group[i];
823 globals->group[0][i] = group[i];
824 globals->group[1][i] = group[i];
838 for (i = 0; i < num; i++) {
840 ODPH_ERR(
"Group destroy failed %i\n", i);
848 static int calc_queue_sizes(test_globals_t *globals, uint32_t queue_size[])
851 test_args_t *args = &globals->args;
852 const uint32_t min_queue_size = 256;
853 uint32_t tot_queues = 0;
856 ODPH_ERR(
"Schedule capability failed\n");
860 for (
int i = 0; i < NUM_PRIOS; i++) {
861 uint32_t events = args->prio[i].events;
862 int queues = args->prio[i].queues;
864 if (!args->prio[i].events_per_queue && queues)
865 events = (events + queues - 1) / queues;
868 if (args->forward_mode != EVENT_FORWARD_NONE)
874 queue_size[i] = ODPH_MAX(events, min_queue_size);
877 ODPH_ERR(
"Warn: queues may not be able to store all events (required size "
878 "%" PRIu32
", max supported %" PRIu32
")\n", queue_size[i],
882 tot_queues += queues;
886 ODPH_ERR(
"Requested %" PRIu32
" queues, max %" PRIu32
" supported\n",
894 static int create_queues(test_globals_t *globals)
897 test_args_t *args = &globals->args;
898 int num_group = args->num_group;
899 uint32_t queue_size[NUM_PRIOS];
901 if (calc_queue_sizes(globals, queue_size))
908 for (
int i = 0; i < NUM_PRIOS; i++) {
909 char name[] =
"sched_XX_YY";
917 param.
size = queue_size[i];
920 name[6] =
'0' + (prio / 10);
921 name[7] =
'0' + prio - (10 * (prio / 10));
923 for (
int j = 0; j < args->prio[i].queues; j++) {
924 name[9] =
'0' + j / 10;
925 name[10] =
'0' + j - 10 * (j / 10);
929 grp = globals->group[i][j % num_group];
936 ODPH_ERR(
"Scheduled queue create failed\n");
940 globals->queue[i][j] = queue;
942 if (args->forward_mode == EVENT_FORWARD_RAND) {
945 randomize_queues(globals->queue[i], args->prio[i].queues, &seed);
954 int main(
int argc,
char *argv[])
958 odph_helper_options_t helper_options;
959 odph_thread_common_param_t thr_common;
960 odph_thread_param_t thr_param;
964 test_globals_t *globals;
969 int num_group, tot_group;
976 test_common_options_t common_options;
978 printf(
"\nODP scheduling latency benchmark starts\n\n");
981 argc = odph_parse_options(argc, argv);
982 if (odph_options(&helper_options)) {
983 ODPH_ERR(
"Error: reading ODP helper options failed.\n");
987 argc = test_common_parse_options(argc, argv);
988 if (test_common_options(&common_options)) {
989 ODPH_ERR(
"Error: reading test options failed\n");
994 init_param.
mem_model = helper_options.mem_model;
996 memset(&args, 0,
sizeof(args));
997 parse_args(argc, argv, &args);
1001 ODPH_ERR(
"ODP global init failed.\n");
1010 ODPH_ERR(
"ODP global init failed.\n");
1016 num_group = args.num_group;
1020 tot_group = args.isolate ? 2 * num_group : num_group;
1024 num_workers = args.cpu_count;
1027 args.cpu_count = num_workers;
1031 printf(
"Test options:\n");
1032 printf(
" Worker threads: %i\n", num_workers);
1034 printf(
" CPU mask: %s\n", cpumaskstr);
1035 printf(
" Test rounds: %iM\n", args.test_rounds);
1036 printf(
" Warm-up rounds: %i\n", args.warm_up_rounds);
1037 printf(
" Isolated groups: %i\n", args.isolate);
1038 printf(
" Number of groups: %i\n", num_group);
1039 printf(
" Created groups: %i\n", tot_group);
1042 shm =
odp_shm_reserve(
"test_globals",
sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 0);
1044 ODPH_ERR(
"Shared memory reserve failed.\n");
1050 memset(globals, 0,
sizeof(test_globals_t));
1051 memcpy(&globals->args, &args,
sizeof(test_args_t));
1053 globals->common_options = common_options;
1061 ODPH_ERR(
"pool capa failed\n");
1066 pool_size = EVENT_POOL_SIZE;
1071 params.
buf.
size =
sizeof(test_event_t);
1073 params.
buf.
num = pool_size;
1079 ODPH_ERR(
"Pool create failed.\n");
1083 globals->pool = pool;
1086 ret = create_groups(globals, group, tot_group);
1087 if (ret != tot_group) {
1088 ODPH_ERR(
"Group create failed.\n");
1094 if (create_queues(globals)) {
1095 ODPH_ERR(
"Creating test queues failed.\n");
1103 memset(thread_tbl, 0,
sizeof(thread_tbl));
1105 odph_thread_common_param_init(&thr_common);
1106 thr_common.instance = instance;
1107 thr_common.cpumask = &cpumask;
1108 thr_common.share_param = 1;
1110 odph_thread_param_init(&thr_param);
1111 thr_param.start = run_thread;
1112 thr_param.arg = NULL;
1115 odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
1118 if (odph_thread_join(thread_tbl, num_workers) != num_workers)
1121 printf(
"ODP scheduling latency test complete\n\n");
1123 for (i = 0; i < NUM_PRIOS; i++) {
1127 num_queues = args.prio[i].queues;
1129 for (j = 0; j < num_queues; j++) {
1130 queue = globals->queue[i][j];
1132 ODPH_ERR(
"Queue destroy failed [%i][%i]\n", i, j);
1140 if (destroy_groups(group, tot_group)) {
1141 ODPH_ERR(
"Group destroy failed\n");
1147 ODPH_ERR(
"Pool destroy failed\n");
1154 ODPH_ERR(
"SHM destroy failed\n");
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.
odp_event_t odp_buffer_to_event(odp_buffer_t buf)
Convert buffer handle to event.
odp_buffer_t odp_buffer_alloc(odp_pool_t pool)
Buffer alloc.
int odp_buffer_is_valid(odp_buffer_t buf)
Check that buffer is valid.
void * odp_buffer_addr(odp_buffer_t buf)
Buffer start address.
odp_buffer_t odp_buffer_from_event(odp_event_t ev)
Get buffer handle from event.
int odp_buffer_alloc_multi(odp_pool_t pool, odp_buffer_t buf[], int num)
Allocate multiple buffers.
#define ODP_BUFFER_INVALID
Invalid buffer.
void odp_buffer_free_multi(const odp_buffer_t buf[], int num)
Free multiple buffers.
#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.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
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.
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_BUFFER
Buffer pool.
int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t events[], int num)
Enqueue multiple events to a queue.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
Enqueue an event to a 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.
uint64_t odp_queue_to_u64(odp_queue_t hdl)
Get printable value for an odp_queue_t.
@ ODP_QUEUE_TYPE_SCHED
Scheduled queue.
int32_t odp_random_test_data(uint8_t *buf, uint32_t len, uint64_t *seed)
Generate repeatable random data for testing purposes.
int odp_schedule_sync_t
Scheduler synchronization method.
#define ODP_SCHED_WAIT
Wait infinitely.
#define ODP_SCHED_SYNC_PARALLEL
Parallel scheduled queues.
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.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
#define ODP_SCHED_SYNC_ORDERED
Ordered queue synchronization.
int odp_schedule_min_prio(void)
Minimum scheduling priority level.
#define ODP_SCHED_GROUP_WORKER
Group of all worker threads.
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.
void odp_schedule_pause(void)
Pause scheduling.
int odp_schedule_max_prio(void)
Maximum scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
int odp_schedule_capability(odp_schedule_capability_t *capa)
Query scheduler capabilities.
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.
void odp_schedule_resume(void)
Resume scheduling.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
odp_shm_t odp_shm_lookup(const char *name)
Lookup for a block of shared memory.
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.
bool odp_bool_t
Boolean type.
void odp_sys_info_print(void)
Print system info.
#define ODP_THREAD_COUNT_MAX
Maximum number of threads supported in build time.
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.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
odp_time_t odp_time_global_strict(void)
Current global time (strict)
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
struct odp_pool_capability_t::@121 buf
Buffer pool capabilities
uint32_t max_num
Maximum number of buffers of any size.
uint32_t num
Number of buffers in the pool.
uint32_t align
Minimum buffer alignment in bytes.
uint32_t size
Minimum buffer size in bytes.
odp_pool_type_t type
Pool type.
struct odp_pool_param_t::@125 buf
Parameters for buffer pools.
odp_schedule_param_t sched
Scheduler parameters.
odp_queue_type_t type
Queue type.
uint32_t max_groups
Maximum number of scheduling groups.
uint32_t max_queues
Maximum number of scheduled (ODP_BLOCKING) queues of the default size.
uint32_t max_queue_size
Maximum number of events a scheduled (ODP_BLOCKING) queue can store simultaneously.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
odp_schedule_sync_t sync
Synchronization method.