21 #include <odp/helper/odph_api.h>
23 #include <export_results.h>
26 #define NUM_ROUNDS 100000u
30 #define INIT_VAL 0x80000000
33 #define DEFAULT_MAX_WORKERS 10
36 #define TEST_MAX_BENCH 70
38 #define TEST_INFO(name, test, validate, op_type) \
39 {name, test, validate, op_type}
42 typedef void (*test_fn_t)(
void *val,
void *out, uint32_t num_round);
44 typedef int (*validate_fn_t)(
void *val,
void *out, uint32_t num_round,
45 uint32_t num_worker,
int private);
54 typedef struct test_options_t {
70 typedef struct test_global_t test_global_t;
73 typedef struct test_thread_ctx_t {
74 test_global_t *global;
83 typedef struct results_t {
84 const char *test_name;
87 double operations_per_cpu;
88 double total_operations;
92 struct test_global_t {
93 test_options_t test_options;
109 test_common_options_t common_options;
110 results_t results[TEST_MAX_BENCH];
116 validate_fn_t validate_fn;
120 static test_global_t *test_global;
122 static inline void test_atomic_load_u32(
void *val,
void *out, uint32_t num_round)
125 uint32_t *result = out;
128 for (uint32_t i = 0; i < num_round; i++)
134 static inline void test_atomic_load_u64(
void *val,
void *out, uint32_t num_round)
137 uint64_t *result = out;
140 for (uint32_t i = 0; i < num_round; i++)
146 static inline void test_atomic_load_u128(
void *val,
void *out, uint32_t num_round)
155 for (uint32_t i = 0; i < num_round; i++) {
158 ret.
u64[0] += cur_val.
u64[0];
159 ret.
u64[1] += cur_val.
u64[1];
165 static inline int validate_atomic_init_val_u32(
void *val,
void *out, uint32_t num_round,
170 uint32_t *result = out;
173 (*result != (uint32_t)INIT_VAL * num_round);
176 static inline int validate_atomic_init_val_u64(
void *val,
void *out, uint32_t num_round,
180 uint64_t *result = out;
183 (*result != (uint64_t)INIT_VAL * num_round);
186 static inline int validate_atomic_init_val_u128(
void *val,
void *out, uint32_t num_round,
192 if (atomic_val.
u64[0] != INIT_VAL || atomic_val.
u64[1] != INIT_VAL)
195 if (result->
u64[0] != (uint64_t)INIT_VAL * num_round ||
196 result->
u64[1] != (uint64_t)INIT_VAL * num_round)
202 static inline void test_atomic_store_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
205 uint32_t new_val = INIT_VAL + 1;
207 for (uint32_t i = 0; i < num_round; i++)
211 static inline void test_atomic_store_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
214 uint64_t new_val = INIT_VAL + 1;
216 for (uint32_t i = 0; i < num_round; i++)
220 static inline void test_atomic_store_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
225 new_val.
u64[0] = INIT_VAL + 1;
226 new_val.
u64[1] = INIT_VAL + 1;
228 for (uint32_t i = 0; i < num_round; i++) {
235 static inline int validate_atomic_num_round_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
243 static inline int validate_atomic_num_round_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
251 static inline int validate_atomic_num_round_u128(
void *val,
void *out
ODP_UNUSED,
252 uint32_t num_round, uint32_t worker
ODP_UNUSED,
257 return (atomic_val.
u64[0] != ((uint64_t)INIT_VAL + num_round) ||
258 atomic_val.
u64[1] != ((uint64_t)INIT_VAL + num_round));
261 static inline void test_atomic_fetch_add_u32(
void *val,
void *out, uint32_t num_round)
264 uint32_t *result = out;
267 for (uint32_t i = 0; i < num_round; i++)
273 static inline void test_atomic_fetch_add_u64(
void *val,
void *out, uint32_t num_round)
276 uint64_t *result = out;
279 for (uint32_t i = 0; i < num_round; i++)
285 static inline int validate_atomic_add_round_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
286 uint32_t num_worker,
int private)
296 static inline int validate_atomic_add_round_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
297 uint32_t num_worker,
int private)
307 static inline void test_atomic_add_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
311 for (uint32_t i = 0; i < num_round; i++)
315 static inline void test_atomic_add_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
319 for (uint32_t i = 0; i < num_round; i++)
323 static inline void test_atomic_fetch_sub_u32(
void *val,
void *out, uint32_t num_round)
326 uint32_t *result = out;
329 for (uint32_t i = 0; i < num_round; i++)
335 static inline void test_atomic_fetch_sub_u64(
void *val,
void *out, uint32_t num_round)
338 uint64_t *result = out;
341 for (uint32_t i = 0; i < num_round; i++)
347 static inline int validate_atomic_sub_round_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
348 uint32_t num_worker,
int private)
358 static inline int validate_atomic_sub_round_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
359 uint32_t num_worker,
int private)
367 ((uint64_t)num_worker * num_round));
370 static inline void test_atomic_sub_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
374 for (uint32_t i = 0; i < num_round; i++)
378 static inline void test_atomic_sub_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
382 for (uint32_t i = 0; i < num_round; i++)
386 static inline void test_atomic_fetch_inc_u32(
void *val,
void *out, uint32_t num_round)
389 uint32_t *result = out;
392 for (uint32_t i = 0; i < num_round; i++)
398 static inline void test_atomic_fetch_inc_u64(
void *val,
void *out, uint32_t num_round)
401 uint64_t *result = out;
404 for (uint32_t i = 0; i < num_round; i++)
410 static inline void test_atomic_inc_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
414 for (uint32_t i = 0; i < num_round; i++)
418 static inline void test_atomic_inc_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
422 for (uint32_t i = 0; i < num_round; i++)
426 static inline void test_atomic_fetch_dec_u32(
void *val,
void *out, uint32_t num_round)
429 uint32_t *result = out;
432 for (uint32_t i = 0; i < num_round; i++)
438 static inline void test_atomic_fetch_dec_u64(
void *val,
void *out, uint32_t num_round)
441 uint64_t *result = out;
444 for (uint32_t i = 0; i < num_round; i++)
450 static inline void test_atomic_dec_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
454 for (uint32_t i = 0; i < num_round; i++)
458 static inline void test_atomic_dec_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
462 for (uint32_t i = 0; i < num_round; i++)
466 static inline void test_atomic_max_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
469 uint32_t new_max = INIT_VAL + 1;
471 for (uint32_t i = 0; i < num_round; i++)
475 static inline void test_atomic_max_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
478 uint64_t new_max = INIT_VAL + 1;
480 for (uint32_t i = 0; i < num_round; i++)
484 static inline int validate_atomic_max_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
489 return (result != ((uint32_t)INIT_VAL + num_round)) && (result != UINT32_MAX);
492 static inline int validate_atomic_max_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
497 return (result != ((uint64_t)INIT_VAL + num_round)) && (result != UINT64_MAX);
500 static inline void test_atomic_fetch_max_u32(
void *val,
void *out, uint32_t num_round)
503 uint32_t *result = out;
504 uint32_t new_max = INIT_VAL + 1, old_max = INIT_VAL;
506 for (uint32_t i = 0; i < num_round; i++)
512 static inline void test_atomic_fetch_max_u64(
void *val,
void *out, uint32_t num_round)
515 uint64_t *result = out;
516 uint64_t new_max = INIT_VAL + 1, old_max = INIT_VAL;
518 for (uint32_t i = 0; i < num_round; i++)
524 static inline int validate_atomic_fetch_max_u32(
void *val,
void *out, uint32_t num_round,
529 uint32_t *output = out;
531 return (result != ((uint32_t)INIT_VAL + num_round) && result != UINT32_MAX) ||
532 (*output != result - 1 && *output != result);
535 static inline int validate_atomic_fetch_max_u64(
void *val,
void *out, uint32_t num_round,
540 uint64_t *output = out;
542 return (result != ((uint64_t)INIT_VAL + num_round) && result != UINT64_MAX) ||
543 (*output != result - 1 && *output != result);
546 static inline void test_atomic_min_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
549 uint32_t new_min = INIT_VAL - 1;
551 for (uint32_t i = 0; i < num_round; i++)
555 static inline void test_atomic_min_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
558 uint64_t new_min = INIT_VAL - 1;
560 for (uint32_t i = 0; i < num_round; i++)
564 static inline int validate_atomic_min_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
569 return result != ((uint32_t)INIT_VAL - num_round) && result != 0;
572 static inline int validate_atomic_min_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
577 return result != ((uint64_t)INIT_VAL - num_round) && result != 0;
580 static inline void test_atomic_fetch_min_u32(
void *val,
void *out, uint32_t num_round)
583 uint32_t *result = out;
584 uint32_t new_min = INIT_VAL - 1, old_min = INIT_VAL;
586 for (uint32_t i = 0; i < num_round; i++)
592 static inline void test_atomic_fetch_min_u64(
void *val,
void *out, uint32_t num_round)
595 uint64_t *result = out;
596 uint64_t new_min = INIT_VAL - 1, old_min = INIT_VAL;
598 for (uint32_t i = 0; i < num_round; i++)
604 static inline int validate_atomic_fetch_min_u32(
void *val,
void *out, uint32_t num_round,
609 uint32_t *output = out;
611 return (result != ((uint32_t)INIT_VAL - num_round) && result != 0) ||
612 (*output != result + 1 && *output != result);
615 static inline int validate_atomic_fetch_min_u64(
void *val,
void *out, uint32_t num_round,
620 uint64_t *output = out;
622 return (result != ((uint64_t)INIT_VAL - num_round) && result != 0) ||
623 (*output != result + 1 && *output != result);
626 static inline void test_atomic_cas_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
629 uint32_t new_val = INIT_VAL + 1;
630 uint32_t old_val = INIT_VAL;
632 for (uint32_t i = 0; i < num_round; i++) {
638 static inline void test_atomic_cas_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
641 uint64_t new_val = INIT_VAL + 1;
642 uint64_t old_val = INIT_VAL;
644 for (uint32_t i = 0; i < num_round; i++) {
650 static inline void test_atomic_cas_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
656 new_val.
u64[0] = INIT_VAL + 1;
657 new_val.
u64[1] = INIT_VAL + 1;
658 old_val.
u64[0] = INIT_VAL;
659 old_val.
u64[1] = INIT_VAL;
661 for (uint32_t i = 0; i < num_round; i++) {
670 static inline int validate_atomic_cas_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
676 return result != ((uint32_t)INIT_VAL + num_round);
678 return result > ((uint32_t)INIT_VAL + num_round);
681 static inline int validate_atomic_cas_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
687 return result != ((uint64_t)INIT_VAL + num_round);
689 return result > ((uint64_t)INIT_VAL + num_round);
692 static inline int validate_atomic_cas_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round,
698 return (result.
u64[0] != ((uint64_t)INIT_VAL + num_round) ||
699 result.
u64[1] != ((uint64_t)INIT_VAL + num_round));
701 return (result.
u64[0] > ((uint64_t)INIT_VAL + num_round) ||
702 result.
u64[1] > ((uint64_t)INIT_VAL + num_round));
705 static inline void test_atomic_xchg_u32(
void *val,
void *out, uint32_t num_round)
708 uint32_t new_val = INIT_VAL + 1;
709 uint32_t *result = out;
712 for (uint32_t i = 0; i < num_round; i++)
718 static inline void test_atomic_xchg_u64(
void *val,
void *out, uint32_t num_round)
721 uint64_t new_val = INIT_VAL + 1;
722 uint64_t *result = out;
725 for (uint32_t i = 0; i < num_round; i++)
731 static inline void test_atomic_bit_set_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
735 for (uint32_t i = 0; i < num_round; i++)
739 static inline void test_atomic_bit_fetch_set_u32(
void *val,
void *out, uint32_t num_round)
742 uint32_t *result = out;
745 for (uint32_t i = 0; i < num_round; i++)
751 static inline void test_atomic_bit_clr_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
755 for (uint32_t i = 0; i < num_round; i++)
759 static inline void test_atomic_bit_fetch_clr_u32(
void *val,
void *out, uint32_t num_round)
762 uint32_t *result = out;
765 for (uint32_t i = 0; i < num_round; i++)
771 static inline void test_atomic_bit_set_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
775 for (uint32_t i = 0; i < num_round; i++)
779 static inline void test_atomic_bit_fetch_set_u64(
void *val,
void *out, uint32_t num_round)
782 uint64_t *result = out;
785 for (uint32_t i = 0; i < num_round; i++)
791 static inline void test_atomic_bit_clr_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
795 for (uint32_t i = 0; i < num_round; i++)
799 static inline void test_atomic_bit_fetch_clr_u64(
void *val,
void *out, uint32_t num_round)
802 uint64_t *result = out;
805 for (uint32_t i = 0; i < num_round; i++)
811 static inline void test_atomic_load_acq_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
814 uint32_t *result = out;
817 for (uint32_t i = 0; i < num_round; i++)
823 static inline void test_atomic_load_acq_u64(
void *val,
void *out, uint32_t num_round)
826 uint64_t *result = out;
829 for (uint32_t i = 0; i < num_round; i++)
835 static inline void test_atomic_store_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
838 uint32_t new_val = INIT_VAL + 1;
840 for (uint32_t i = 0; i < num_round; i++)
844 static inline void test_atomic_store_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
847 uint64_t new_val = INIT_VAL + 1;
849 for (uint32_t i = 0; i < num_round; i++)
853 static inline void test_atomic_add_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
857 for (uint32_t i = 0; i < num_round; i++)
861 static inline void test_atomic_add_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
865 for (uint32_t i = 0; i < num_round; i++)
869 static inline void test_atomic_sub_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
873 for (uint32_t i = 0; i < num_round; i++)
877 static inline void test_atomic_sub_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
881 for (uint32_t i = 0; i < num_round; i++)
885 static inline void test_atomic_cas_acq_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
888 uint32_t new_val = INIT_VAL + 1;
889 uint32_t old_val = INIT_VAL;
891 for (uint32_t i = 0; i < num_round; i++) {
897 static inline void test_atomic_cas_acq_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
900 uint64_t new_val = INIT_VAL + 1;
901 uint64_t old_val = INIT_VAL;
903 for (uint32_t i = 0; i < num_round; i++) {
909 static inline void test_atomic_cas_acq_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
915 new_val.
u64[0] = INIT_VAL + 1;
916 new_val.
u64[1] = INIT_VAL + 1;
917 old_val.
u64[0] = INIT_VAL;
918 old_val.
u64[1] = INIT_VAL;
920 for (uint32_t i = 0; i < num_round; i++) {
929 static inline void test_atomic_cas_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
932 uint32_t new_val = INIT_VAL + 1;
933 uint32_t old_val = INIT_VAL;
935 for (uint32_t i = 0; i < num_round; i++) {
941 static inline void test_atomic_cas_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
944 uint64_t new_val = INIT_VAL + 1;
945 uint64_t old_val = INIT_VAL;
947 for (uint32_t i = 0; i < num_round; i++) {
953 static inline void test_atomic_cas_rel_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
959 new_val.
u64[0] = INIT_VAL + 1;
960 new_val.
u64[1] = INIT_VAL + 1;
961 old_val.
u64[0] = INIT_VAL;
962 old_val.
u64[1] = INIT_VAL;
964 for (uint32_t i = 0; i < num_round; i++) {
973 static inline void test_atomic_cas_acq_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
976 uint32_t new_val = INIT_VAL + 1;
977 uint32_t old_val = INIT_VAL;
979 for (uint32_t i = 0; i < num_round; i++) {
985 static inline void test_atomic_cas_acq_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
988 uint64_t new_val = INIT_VAL + 1;
989 uint64_t old_val = INIT_VAL;
991 for (uint32_t i = 0; i < num_round; i++) {
997 static inline void test_atomic_cas_acq_rel_u128(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
1003 new_val.
u64[0] = INIT_VAL + 1;
1004 new_val.
u64[1] = INIT_VAL + 1;
1005 old_val.
u64[0] = INIT_VAL;
1006 old_val.
u64[1] = INIT_VAL;
1008 for (uint32_t i = 0; i < num_round; i++) {
1017 static inline void test_atomic_bit_set_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
1021 for (uint32_t i = 0; i < num_round; i++)
1025 static inline void test_atomic_bit_clr_rel_u32(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
1029 for (uint32_t i = 0; i < num_round; i++)
1033 static inline void test_atomic_bit_set_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
1037 for (uint32_t i = 0; i < num_round; i++)
1041 static inline void test_atomic_bit_clr_rel_u64(
void *val,
void *out
ODP_UNUSED, uint32_t num_round)
1045 for (uint32_t i = 0; i < num_round; i++)
1049 static void print_usage(
void)
1052 "Atomic operations performance test\n"
1054 "Usage: odp_atomic_perf [options]\n"
1056 " -c, --num_cpu Number of CPUs (worker threads). 0: all available CPUs (or max %d) (default)\n"
1057 " -r, --num_round Number of rounds (default %u)\n"
1058 " -p, --private 0: The same atomic variable is shared between threads (default)\n"
1059 " 1: Atomic variables are private to each thread\n"
1060 " -h, --help This help\n"
1061 "\n", DEFAULT_MAX_WORKERS, NUM_ROUNDS);
1064 static void print_info(test_options_t *test_options)
1068 printf(
"\nAtomic operations performance test configuration:\n");
1069 printf(
" num cpu %u\n", test_options->num_cpu);
1070 printf(
" num rounds %u\n", test_options->num_round);
1071 printf(
" private %i\n", test_options->private);
1077 printf(
"\nAtomic operations lock-free:\n");
1078 printf(
" odp_atomic_load_u64: %" PRIu32
"\n", atomic_ops.
op.
load);
1079 printf(
" odp_atomic_store_u64: %" PRIu32
"\n", atomic_ops.
op.
store);
1080 printf(
" odp_atomic_fetch_add_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_add);
1081 printf(
" odp_atomic_add_u64: %" PRIu32
"\n", atomic_ops.
op.
add);
1082 printf(
" odp_atomic_fetch_sub_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_sub);
1083 printf(
" odp_atomic_sub_u64: %" PRIu32
"\n", atomic_ops.
op.
sub);
1084 printf(
" odp_atomic_fetch_inc_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_inc);
1085 printf(
" odp_atomic_inc_u64: %" PRIu32
"\n", atomic_ops.
op.
inc);
1086 printf(
" odp_atomic_fetch_dec_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_dec);
1087 printf(
" odp_atomic_dec_u64: %" PRIu32
"\n", atomic_ops.
op.
dec);
1088 printf(
" odp_atomic_min_u64: %" PRIu32
"\n", atomic_ops.
op.
min);
1089 printf(
" odp_atomic_fetch_min_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_min);
1090 printf(
" odp_atomic_max_u64: %" PRIu32
"\n", atomic_ops.
op.
max);
1091 printf(
" odp_atomic_fetch_max_u64: %" PRIu32
"\n", atomic_ops.
op.
fetch_max);
1092 printf(
" odp_atomic_cas_u64: %" PRIu32
"\n", atomic_ops.
op.
cas);
1093 printf(
" odp_atomic_xchg_u64: %" PRIu32
"\n", atomic_ops.
op.
xchg);
1094 printf(
" odp_atomic_bit_fetch_set_u64: %" PRIu32
"\n", atomic_ops.
op.
bit_fetch_set);
1095 printf(
" odp_atomic_bit_set_u64: %" PRIu32
"\n", atomic_ops.
op.
bit_set);
1096 printf(
" odp_atomic_bit_fetch_clr_u64: %" PRIu32
"\n", atomic_ops.
op.
bit_fetch_clr);
1097 printf(
" odp_atomic_bit_clr_u64: %" PRIu32
"\n", atomic_ops.
op.
bit_clr);
1102 printf(
" odp_atomic_load_u128: %" PRIu32
"\n", atomic_ops.
op.
load);
1103 printf(
" odp_atomic_store_u128: %" PRIu32
"\n", atomic_ops.
op.
store);
1104 printf(
" odp_atomic_cas_u128: %" PRIu32
"\n", atomic_ops.
op.
cas);
1109 static int output_summary(test_global_t *global)
1111 int results_size = ODPH_ARRAY_SIZE(global->results);
1114 if (global->common_options.is_export) {
1115 if (test_common_write(
"function name,ops/cpu (M/s),total ops (M/s),"
1116 "cycles/op,nsec/op\n")) {
1117 test_common_write_term();
1122 printf(
"Average results over %i threads:\n", global->test_options.num_cpu);
1123 printf(
"%-33s %-15s %-17s %-11s %-11s\n",
"function name",
"ops/cpu (M/s)",
1124 "total ops (M/s)",
"cycles/op",
"nsec/op");
1125 printf(
"-----------------------------------------------------------------------------"
1126 "-----------------------\n");
1127 for (
int i = 0; i < results_size && global->results[i].test_name; i++) {
1128 res = global->results[i];
1129 printf(
"[%02d] %-28s %-15.2f %-17.2f %-11.2f %-11.2f\n", i + 1,
1130 res.test_name, res.operations_per_cpu, res.total_operations,
1131 res.cycles_per_op, res.nsec_per_op);
1132 if (global->common_options.is_export) {
1133 if (test_common_write(
"%s,%f,%f,%f,%f\n", res.test_name,
1134 res.operations_per_cpu, res.total_operations,
1135 res.cycles_per_op, res.nsec_per_op)) {
1136 test_common_write_term();
1142 if (global->common_options.is_export)
1143 test_common_write_term();
1148 static int parse_options(
int argc,
char *argv[], test_options_t *test_options)
1153 static const struct option longopts[] = {
1154 {
"num_cpu", required_argument, NULL,
'c'},
1155 {
"num_round", required_argument, NULL,
'r'},
1156 {
"private", required_argument, NULL,
'p'},
1157 {
"help", no_argument, NULL,
'h'},
1161 static const char *shortopts =
"+c:r:p:h";
1163 memset(test_options, 0,
sizeof(test_options_t));
1164 test_options->num_cpu = 0;
1165 test_options->num_round = NUM_ROUNDS;
1166 test_options->private = 0;
1169 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
1176 test_options->num_cpu = atoi(optarg);
1179 test_options->num_round = atol(optarg);
1182 test_options->private = atoi(optarg);
1193 if (test_options->num_round < 1) {
1194 ODPH_ERR(
"Invalid number of test rounds: %" PRIu32
"\n", test_options->num_round);
1201 static int set_num_cpu(test_global_t *global)
1204 test_options_t *test_options = &global->test_options;
1205 int num_cpu = test_options->num_cpu;
1216 if (max_num > DEFAULT_MAX_WORKERS)
1217 max_num = DEFAULT_MAX_WORKERS;
1222 if (num_cpu && ret != num_cpu) {
1223 ODPH_ERR(
"Too many workers. Max supported %i.\n", ret);
1229 if (ret > max_num) {
1230 ODPH_ERR(
"Too many cpus from odp_cpumask_default_worker(): %i\n", ret);
1235 test_options->num_cpu = num_cpu;
1243 static int init_test(test_global_t *global,
const char *name, op_bit_t type)
1247 init_val.
u64[0] = INIT_VAL;
1248 init_val.
u64[1] = INIT_VAL;
1250 printf(
"TEST: %s\n", name);
1252 if (type == OP_32BIT)
1254 else if (type == OP_64BIT)
1256 else if (type == OP_128BIT)
1262 if (type == OP_32BIT) {
1263 global->output[i].u32 = 0;
1265 }
else if (type == OP_64BIT) {
1266 global->output[i].u64 = 0;
1269 global->output[i].u128.u64[0] = 0;
1270 global->output[i].u128.u64[1] = 0;
1277 static int run_test(
void *arg)
1283 test_thread_ctx_t *thread_ctx = arg;
1284 test_global_t *global = thread_ctx->global;
1285 test_options_t *test_options = &global->test_options;
1286 uint32_t num_round = test_options->num_round;
1287 uint32_t idx = thread_ctx->idx;
1288 test_fn_t test_func = thread_ctx->func;
1289 op_bit_t type = thread_ctx->type;
1292 uint32_t out_u32 = 0;
1293 uint64_t out_u64 = 0;
1296 out_u128.
u64[0] = 0;
1297 out_u128.
u64[1] = 0;
1299 if (type == OP_32BIT) {
1300 val = &global->atomic_u32;
1302 }
else if (type == OP_64BIT) {
1303 val = &global->atomic_u64;
1306 val = &global->atomic_u128;
1310 if (global->test_options.private) {
1311 if (type == OP_32BIT)
1312 val = &global->atomic_private[idx].
u32;
1313 else if (type == OP_64BIT)
1314 val = &global->atomic_private[idx].u64;
1316 val = &global->atomic_private[idx].u128;
1325 test_func(val, out, num_round);
1334 thread_ctx->nsec = nsec;
1335 thread_ctx->cycles = cycles;
1336 if (type == OP_32BIT)
1337 global->output[idx].u32 = out_u32;
1338 else if (type == OP_64BIT)
1339 global->output[idx].u64 = out_u64;
1341 global->output[idx].u128 = out_u128;
1346 static int start_workers(test_global_t *global,
odp_instance_t instance,
1347 test_fn_t func, op_bit_t type)
1349 odph_thread_common_param_t param;
1351 test_options_t *test_options = &global->test_options;
1352 int num_cpu = test_options->num_cpu;
1353 odph_thread_param_t thr_param[num_cpu];
1355 odph_thread_common_param_init(¶m);
1356 param.instance = instance;
1357 param.cpumask = &global->cpumask;
1359 for (i = 0; i < num_cpu; i++) {
1360 test_thread_ctx_t *thread_ctx = &global->thread_ctx[i];
1362 thread_ctx->global = global;
1363 thread_ctx->idx = i;
1364 thread_ctx->func = func;
1365 thread_ctx->type = type;
1367 odph_thread_param_init(&thr_param[i]);
1369 thr_param[i].start = run_test;
1370 thr_param[i].arg = thread_ctx;
1373 ret = odph_thread_create(global->thread_tbl, ¶m, thr_param, num_cpu);
1374 if (ret != num_cpu) {
1375 ODPH_ERR(
"Failed to create all threads %i\n", ret);
1382 static int validate_results(test_global_t *global, validate_fn_t validate, op_bit_t type)
1385 test_options_t *test_options = &global->test_options;
1386 uint32_t num_round = test_options->num_round;
1387 int num_cpu = test_options->num_cpu;
1388 int private = global->test_options.private;
1392 for (i = 0; i < num_cpu; i++) {
1393 if (type == OP_32BIT) {
1394 out = &global->output[i].u32;
1395 val = &global->atomic_u32;
1397 val = &global->atomic_private[i].u32;
1398 }
else if (type == OP_64BIT) {
1399 out = &global->output[i].u64;
1400 val = &global->atomic_u64;
1402 val = &global->atomic_private[i].u64;
1404 out = &global->output[i].u128;
1405 val = &global->atomic_u128;
1407 val = &global->atomic_private[i].u128;
1410 if (validate != NULL && validate(val, out, num_round, num_cpu,
private))
1419 static test_case_t test_suite[] = {
1420 TEST_INFO(
"odp_atomic_load_u32", test_atomic_load_u32,
1421 validate_atomic_init_val_u32, OP_32BIT),
1422 TEST_INFO(
"odp_atomic_store_u32", test_atomic_store_u32,
1423 validate_atomic_num_round_u32, OP_32BIT),
1424 TEST_INFO(
"odp_atomic_fetch_add_u32", test_atomic_fetch_add_u32,
1425 validate_atomic_add_round_u32, OP_32BIT),
1426 TEST_INFO(
"odp_atomic_add_u32", test_atomic_add_u32,
1427 validate_atomic_add_round_u32, OP_32BIT),
1428 TEST_INFO(
"odp_atomic_fetch_sub_u32", test_atomic_fetch_sub_u32,
1429 validate_atomic_sub_round_u32, OP_32BIT),
1430 TEST_INFO(
"odp_atomic_sub_u32", test_atomic_sub_u32,
1431 validate_atomic_sub_round_u32, OP_32BIT),
1432 TEST_INFO(
"odp_atomic_fetch_inc_u32", test_atomic_fetch_inc_u32,
1433 validate_atomic_add_round_u32, OP_32BIT),
1434 TEST_INFO(
"odp_atomic_inc_u32", test_atomic_inc_u32,
1435 validate_atomic_add_round_u32, OP_32BIT),
1436 TEST_INFO(
"odp_atomic_fetch_dec_u32", test_atomic_fetch_dec_u32,
1437 validate_atomic_sub_round_u32, OP_32BIT),
1438 TEST_INFO(
"odp_atomic_dec_u32", test_atomic_dec_u32,
1439 validate_atomic_sub_round_u32, OP_32BIT),
1440 TEST_INFO(
"odp_atomic_max_u32", test_atomic_max_u32,
1441 validate_atomic_max_u32, OP_32BIT),
1442 TEST_INFO(
"odp_atomic_fetch_max_u32", test_atomic_fetch_max_u32,
1443 validate_atomic_fetch_max_u32, OP_32BIT),
1444 TEST_INFO(
"odp_atomic_min_u32", test_atomic_min_u32,
1445 validate_atomic_min_u32, OP_32BIT),
1446 TEST_INFO(
"odp_atomic_fetch_min_u32", test_atomic_fetch_min_u32,
1447 validate_atomic_fetch_min_u32, OP_32BIT),
1448 TEST_INFO(
"odp_atomic_cas_u32", test_atomic_cas_u32,
1449 validate_atomic_cas_u32, OP_32BIT),
1450 TEST_INFO(
"odp_atomic_xchg_u32", test_atomic_xchg_u32,
1451 validate_atomic_num_round_u32, OP_32BIT),
1452 TEST_INFO(
"odp_atomic_bit_set_u32", test_atomic_bit_set_u32,
1454 TEST_INFO(
"odp_atomic_bit_fetch_set_u32", test_atomic_bit_fetch_set_u32,
1456 TEST_INFO(
"odp_atomic_bit_clr_u32", test_atomic_bit_clr_u32,
1458 TEST_INFO(
"odp_atomic_bit_fetch_clr_u32", test_atomic_bit_fetch_clr_u32,
1460 TEST_INFO(
"odp_atomic_load_acq_u32", test_atomic_load_acq_u32,
1461 validate_atomic_init_val_u32, OP_32BIT),
1462 TEST_INFO(
"odp_atomic_store_rel_u32", test_atomic_store_rel_u32,
1463 validate_atomic_num_round_u32, OP_32BIT),
1464 TEST_INFO(
"odp_atomic_add_rel_u32", test_atomic_add_rel_u32,
1465 validate_atomic_add_round_u32, OP_32BIT),
1466 TEST_INFO(
"odp_atomic_sub_rel_u32", test_atomic_sub_rel_u32,
1467 validate_atomic_sub_round_u32, OP_32BIT),
1468 TEST_INFO(
"odp_atomic_cas_acq_u32", test_atomic_cas_acq_u32,
1469 validate_atomic_cas_u32, OP_32BIT),
1470 TEST_INFO(
"odp_atomic_cas_rel_u32", test_atomic_cas_rel_u32,
1471 validate_atomic_cas_u32, OP_32BIT),
1472 TEST_INFO(
"odp_atomic_cas_acq_rel_u32", test_atomic_cas_acq_rel_u32,
1473 validate_atomic_cas_u32, OP_32BIT),
1474 TEST_INFO(
"odp_atomic_bit_set_rel_u32", test_atomic_bit_set_rel_u32,
1476 TEST_INFO(
"odp_atomic_bit_clr_rel_u32", test_atomic_bit_clr_rel_u32,
1478 TEST_INFO(
"odp_atomic_load_u64", test_atomic_load_u64,
1479 validate_atomic_init_val_u64, OP_64BIT),
1480 TEST_INFO(
"odp_atomic_store_u64", test_atomic_store_u64,
1481 validate_atomic_num_round_u64, OP_64BIT),
1482 TEST_INFO(
"odp_atomic_fetch_add_u64", test_atomic_fetch_add_u64,
1483 validate_atomic_add_round_u64, OP_64BIT),
1484 TEST_INFO(
"odp_atomic_add_u64", test_atomic_add_u64,
1485 validate_atomic_add_round_u64, OP_64BIT),
1486 TEST_INFO(
"odp_atomic_fetch_sub_u64", test_atomic_fetch_sub_u64,
1487 validate_atomic_sub_round_u64, OP_64BIT),
1488 TEST_INFO(
"odp_atomic_sub_u64", test_atomic_sub_u64,
1489 validate_atomic_sub_round_u64, OP_64BIT),
1490 TEST_INFO(
"odp_atomic_fetch_inc_u64", test_atomic_fetch_inc_u64,
1491 validate_atomic_add_round_u64, OP_64BIT),
1492 TEST_INFO(
"odp_atomic_inc_u64", test_atomic_inc_u64,
1493 validate_atomic_add_round_u64, OP_64BIT),
1494 TEST_INFO(
"odp_atomic_fetch_dec_u64", test_atomic_fetch_dec_u64,
1495 validate_atomic_sub_round_u64, OP_64BIT),
1496 TEST_INFO(
"odp_atomic_dec_u64", test_atomic_dec_u64,
1497 validate_atomic_sub_round_u64, OP_64BIT),
1498 TEST_INFO(
"odp_atomic_max_u64", test_atomic_max_u64,
1499 validate_atomic_max_u64, OP_64BIT),
1500 TEST_INFO(
"odp_atomic_fetch_max_u64", test_atomic_fetch_max_u64,
1501 validate_atomic_fetch_max_u64, OP_64BIT),
1502 TEST_INFO(
"odp_atomic_min_u64", test_atomic_min_u64,
1503 validate_atomic_min_u64, OP_64BIT),
1504 TEST_INFO(
"odp_atomic_fetch_min_u64", test_atomic_fetch_min_u64,
1505 validate_atomic_fetch_min_u64, OP_64BIT),
1506 TEST_INFO(
"odp_atomic_cas_u64", test_atomic_cas_u64,
1507 validate_atomic_cas_u64, OP_64BIT),
1508 TEST_INFO(
"odp_atomic_xchg_u64", test_atomic_xchg_u64,
1509 validate_atomic_num_round_u64, OP_64BIT),
1510 TEST_INFO(
"odp_atomic_bit_set_u64", test_atomic_bit_set_u64,
1512 TEST_INFO(
"odp_atomic_bit_fetch_set_u64", test_atomic_bit_fetch_set_u64,
1514 TEST_INFO(
"odp_atomic_bit_clr_u64", test_atomic_bit_clr_u64,
1516 TEST_INFO(
"odp_atomic_bit_fetch_clr_u64", test_atomic_bit_fetch_clr_u64,
1518 TEST_INFO(
"odp_atomic_load_acq_u64", test_atomic_load_acq_u64,
1519 validate_atomic_init_val_u64, OP_64BIT),
1520 TEST_INFO(
"odp_atomic_store_rel_u64", test_atomic_store_rel_u64,
1521 validate_atomic_num_round_u64, OP_64BIT),
1522 TEST_INFO(
"odp_atomic_add_rel_u64", test_atomic_add_rel_u64,
1523 validate_atomic_add_round_u64, OP_64BIT),
1524 TEST_INFO(
"odp_atomic_sub_rel_u64", test_atomic_sub_rel_u64,
1525 validate_atomic_sub_round_u64, OP_64BIT),
1526 TEST_INFO(
"odp_atomic_cas_acq_u64", test_atomic_cas_acq_u64,
1527 validate_atomic_cas_u64, OP_64BIT),
1528 TEST_INFO(
"odp_atomic_cas_rel_u64", test_atomic_cas_rel_u64,
1529 validate_atomic_cas_u64, OP_64BIT),
1530 TEST_INFO(
"odp_atomic_cas_acq_rel_u64", test_atomic_cas_acq_rel_u64,
1531 validate_atomic_cas_u64, OP_64BIT),
1532 TEST_INFO(
"odp_atomic_bit_set_rel_u64", test_atomic_bit_set_rel_u64,
1534 TEST_INFO(
"odp_atomic_bit_clr_rel_u64", test_atomic_bit_clr_rel_u64,
1536 TEST_INFO(
"odp_atomic_load_u128", test_atomic_load_u128,
1537 validate_atomic_init_val_u128, OP_128BIT),
1538 TEST_INFO(
"odp_atomic_store_u128", test_atomic_store_u128,
1539 validate_atomic_num_round_u128, OP_128BIT),
1540 TEST_INFO(
"odp_atomic_cas_u128", test_atomic_cas_u128,
1541 validate_atomic_cas_u128, OP_128BIT),
1542 TEST_INFO(
"odp_atomic_cas_acq_u128", test_atomic_cas_acq_u128,
1543 validate_atomic_cas_u128, OP_128BIT),
1544 TEST_INFO(
"odp_atomic_cas_rel_u128", test_atomic_cas_rel_u128,
1545 validate_atomic_cas_u128, OP_128BIT),
1546 TEST_INFO(
"odp_atomic_cas_acq_rel_u128", test_atomic_cas_acq_rel_u128,
1547 validate_atomic_cas_u128, OP_128BIT),
1551 "Result array is too small to hold all the results");
1553 static void output_results(test_global_t *global,
int idx)
1556 double nsec_ave, nsec_per_op, cycles_per_op, operations_per_cpu, total_operations;
1557 test_options_t *test_options = &global->test_options;
1558 int num_cpu = test_options->num_cpu;
1559 uint32_t num_round = test_options->num_round;
1560 uint64_t nsec_sum = 0;
1561 uint64_t cycles_sum = 0;
1563 global->results[idx].test_name = test_suite[idx].name;
1566 nsec_sum += global->thread_ctx[i].nsec;
1567 cycles_sum += global->thread_ctx[i].cycles;
1570 if (nsec_sum == 0 || cycles_sum == 0) {
1571 printf(
"No results.\n");
1575 nsec_ave = (double)nsec_sum / num_cpu;
1576 nsec_per_op = (double)nsec_sum / (num_cpu * num_round);
1577 cycles_per_op = (double)cycles_sum / (num_cpu * num_round);
1580 operations_per_cpu = num_round / (nsec_ave / 1000.0);
1581 total_operations = (num_cpu * num_round) / (nsec_ave / 1000.0);
1583 global->results[idx].cycles_per_op = cycles_per_op;
1584 global->results[idx].operations_per_cpu = operations_per_cpu;
1585 global->results[idx].nsec_per_op = nsec_per_op;
1586 global->results[idx].total_operations = total_operations;
1588 printf(
"---------------------------------------------\n");
1589 printf(
"Per thread results (Millions of ops per sec):\n");
1590 printf(
"---------------------------------------------\n");
1591 printf(
" 1 2 3 4 5 6 7 8 9 10");
1594 if (global->thread_ctx[i].nsec) {
1595 if ((num % 10) == 0)
1598 printf(
"%8.2f ", num_round / (global->thread_ctx[i].nsec / 1000.0));
1604 printf(
"Average results over %i threads:\n", num_cpu);
1605 printf(
"---------------------------------------\n");
1607 printf(
" cycles per op: %8.2f\n", cycles_per_op);
1608 printf(
" nsec per op: %8.2f\n", nsec_per_op);
1609 printf(
" ops per cpu: %8.2fM ops/sec\n", operations_per_cpu);
1610 printf(
" total ops: %8.2fM ops/sec\n", total_operations);
1614 int main(
int argc,
char **argv)
1616 odph_helper_options_t helper_options;
1620 test_options_t test_options;
1622 test_common_options_t common_options;
1625 argc = odph_parse_options(argc, argv);
1626 if (odph_options(&helper_options)) {
1627 ODPH_ERR(
"Error: reading ODP helper options failed.\n");
1631 argc = test_common_parse_options(argc, argv);
1632 if (test_common_options(&common_options)) {
1633 ODPH_ERR(
"Error while reading test options, exiting\n");
1637 if (parse_options(argc, argv, &test_options))
1651 init.
mem_model = helper_options.mem_model;
1655 ODPH_ERR(
"Global init failed.\n");
1661 ODPH_ERR(
"Local init failed.\n");
1667 ODP_CACHE_LINE_SIZE, 0);
1670 ODPH_ERR(
"Shared memory reserve failed.\n");
1675 if (test_global == NULL) {
1676 ODPH_ERR(
"Shared memory alloc failed.\n");
1679 memset(test_global, 0,
sizeof(test_global_t));
1680 test_global->test_options = test_options;
1681 test_global->common_options = common_options;
1685 if (set_num_cpu(test_global))
1688 print_info(&test_global->test_options);
1691 num_tests = ODPH_ARRAY_SIZE(test_suite);
1693 for (i = 0; i < num_tests; i++) {
1695 if (init_test(test_global, test_suite[i].name, test_suite[i].type)) {
1696 ODPH_ERR(
"Failed to initialize atomics.\n");
1701 if (start_workers(test_global, instance, test_suite[i].test_fn, test_suite[i].type))
1705 odph_thread_join(test_global->thread_tbl, test_global->test_options.num_cpu);
1707 output_results(test_global, i);
1710 if (validate_results(test_global, test_suite[i].validate_fn, test_suite[i].type)) {
1711 ODPH_ERR(
"Test %s result validation failed.\n", test_suite[i].name);
1716 if (output_summary(test_global)) {
1717 ODPH_ERR(
"Outputting summary failed.\n");
1722 ODPH_ERR(
"Shm free failed.\n");
1727 ODPH_ERR(
"Local terminate failed.\n");
1732 ODPH_ERR(
"Global terminate failed.\n");
void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
Initialize atomic uint32 variable.
void odp_atomic_store_rel_u64(odp_atomic_u64_t *atom, uint64_t val)
Store value to atomic uint64 variable using RELEASE memory ordering.
int odp_atomic_cas_rel_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t new_val)
Compare and swap atomic uint64 variable using RELEASE memory ordering.
uint32_t odp_atomic_fetch_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
Fetch and update maximum value of atomic uint32 variable.
void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
Update maximum value of atomic uint64 variable.
void odp_atomic_bit_set_u32(odp_atomic_u32_t *atom, uint32_t bits)
Set bits in atomic uint32 variable.
int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val, uint32_t new_val)
Compare and swap atomic uint32 variable using ACQUIRE memory ordering.
int odp_atomic_cas_acq_rel_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t new_val)
Compare and swap atomic uint64 variable using ACQUIRE-and-RELEASE memory ordering.
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.
void odp_atomic_dec_u64(odp_atomic_u64_t *atom)
Decrement atomic uint64 variable.
void odp_atomic_bit_set_u64(odp_atomic_u64_t *atom, uint64_t bits)
Set bits in atomic uint64 variable.
void odp_atomic_bit_clr_rel_u64(odp_atomic_u64_t *atom, uint64_t bits)
Clear bits in atomic uint64 variable using RELEASE memory ordering.
void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
Initialize atomic uint64 variable.
void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
Update maximum value of atomic uint32 variable.
uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, uint32_t val)
Fetch and subtract from atomic uint32 variable.
uint64_t odp_atomic_fetch_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
Fetch and update maximum value of atomic uint64 variable.
int odp_atomic_cas_acq_rel_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, odp_u128_t new_val)
Compare and swap atomic odp_u128_t variable using ACQUIRE-and-RELEASE memory ordering.
uint64_t odp_atomic_load_acq_u64(odp_atomic_u64_t *atom)
Load value of atomic uint64 variable using ACQUIRE memory ordering.
uint64_t odp_atomic_xchg_u64(odp_atomic_u64_t *atom, uint64_t new_val)
Exchange value of atomic uint64 variable.
int odp_atomic_lock_free_u64(odp_atomic_op_t *atomic_op)
Query which atomic uint64 operations are lock-free.
uint64_t odp_atomic_fetch_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
Fetch and update minimum value of atomic uint64_t variable.
uint32_t odp_atomic_fetch_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
Fetch and update minimum value of atomic uint32 variable.
void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
Decrement atomic uint32 variable.
void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
Update minimum value of atomic uint32 variable.
uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom)
Fetch and increment atomic uint32 variable.
uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, uint32_t val)
Fetch and add to atomic uint32 variable.
uint64_t odp_atomic_bit_fetch_clr_u64(odp_atomic_u64_t *atom, uint64_t bits)
Fetch value and clear bits in atomic uint64 variable.
uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable using ACQUIRE memory ordering.
uint32_t odp_atomic_bit_fetch_set_u32(odp_atomic_u32_t *atom, uint32_t bits)
Fetch value and set bits in atomic uint32 variable.
void odp_atomic_bit_set_rel_u64(odp_atomic_u64_t *atom, uint64_t bits)
Set bits in atomic uint64 variable using RELEASE memory ordering.
uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom)
Fetch and decrement atomic uint64 variable.
int odp_atomic_cas_u32(odp_atomic_u32_t *atom, uint32_t *old_val, uint32_t new_val)
Compare and swap atomic uint32 variable.
void odp_atomic_add_rel_u32(odp_atomic_u32_t *atom, uint32_t val)
Add to atomic uint32 variable using RELEASE memory ordering.
int odp_atomic_cas_rel_u32(odp_atomic_u32_t *atom, uint32_t *old_val, uint32_t new_val)
Compare and swap atomic uint32 variable using RELEASE memory ordering.
void odp_atomic_bit_set_rel_u32(odp_atomic_u32_t *atom, uint32_t bits)
Set bits in atomic uint32 variable using RELEASE memory ordering.
void odp_atomic_bit_clr_u32(odp_atomic_u32_t *atom, uint32_t bits)
Clear bits in atomic uint32 variable.
int odp_atomic_cas_acq_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, odp_u128_t new_val)
Compare and swap atomic odp_u128_t variable using ACQUIRE memory ordering.
void odp_atomic_inc_u64(odp_atomic_u64_t *atom)
Increment atomic uint64 variable.
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *atom, uint64_t val)
Fetch and subtract from atomic uint64 variable.
int odp_atomic_cas_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, odp_u128_t new_val)
Compare and swap atomic odp_u128_t variable.
int odp_atomic_cas_rel_u128(odp_atomic_u128_t *atom, odp_u128_t *old_val, odp_u128_t new_val)
Compare and swap atomic odp_u128_t variable using RELEASE memory ordering.
int odp_atomic_lock_free_u128(odp_atomic_op_t *atomic_op)
Query which atomic odp_atomic_u128_t operations are lock-free.
void odp_atomic_sub_rel_u32(odp_atomic_u32_t *atom, uint32_t val)
Subtract from atomic uint32 variable using RELEASE memory ordering.
uint32_t odp_atomic_bit_fetch_clr_u32(odp_atomic_u32_t *atom, uint32_t bits)
Fetch value and clear bits in atomic uint32 variable.
void odp_atomic_sub_u64(odp_atomic_u64_t *atom, uint64_t val)
Subtract from atomic uint64 variable.
odp_u128_t odp_atomic_load_u128(odp_atomic_u128_t *atom)
Load value of atomic odp_u128_t variable.
uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom)
Fetch and decrement atomic uint32 variable.
void odp_atomic_store_u64(odp_atomic_u64_t *atom, uint64_t val)
Store value to atomic uint64 variable.
void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val)
Add to atomic uint64 variable.
int odp_atomic_cas_acq_rel_u32(odp_atomic_u32_t *atom, uint32_t *old_val, uint32_t new_val)
Compare and swap atomic uint32 variable using ACQUIRE-and-RELEASE memory ordering.
int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t new_val)
Compare and swap atomic uint64 variable.
void odp_atomic_add_rel_u64(odp_atomic_u64_t *atom, uint64_t val)
Add to atomic uint64 variable using RELEASE memory ordering.
uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *atom)
Fetch and increment atomic uint64 variable.
uint32_t odp_atomic_xchg_u32(odp_atomic_u32_t *atom, uint32_t new_val)
Exchange value of atomic uint32 variable.
uint64_t odp_atomic_bit_fetch_set_u64(odp_atomic_u64_t *atom, uint64_t bits)
Fetch value and set bits in atomic uint64 variable.
void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
Update minimum value of atomic uint64 variable.
void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val)
Subtract from atomic uint32 variable.
int odp_atomic_cas_acq_u64(odp_atomic_u64_t *atom, uint64_t *old_val, uint64_t new_val)
Compare and swap atomic uint64 variable using ACQUIRE memory ordering.
void odp_atomic_init_u128(odp_atomic_u128_t *atom, odp_u128_t val)
Initialize atomic odp_u128_t variable.
void odp_atomic_sub_rel_u64(odp_atomic_u64_t *atom, uint64_t val)
Subtract from atomic uint64 variable using RELEASE memory ordering.
void odp_atomic_store_u128(odp_atomic_u128_t *atom, odp_u128_t val)
Store value to atomic odp_u128_t variable.
void odp_atomic_bit_clr_u64(odp_atomic_u64_t *atom, uint64_t bits)
Clear bits in atomic uint64 variable.
void odp_atomic_bit_clr_rel_u32(odp_atomic_u32_t *atom, uint32_t bits)
Clear bits in atomic uint32 variable using RELEASE memory ordering.
uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *atom, uint64_t val)
Fetch and add to atomic uint64 variable.
uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom)
Load value of atomic uint64 variable.
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_ALIGNED_CACHE
Defines type/struct/variable to be cache line size aligned.
#define ODP_UNUSED
Intentionally unused variables of functions.
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_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
#define ODP_STATIC_ASSERT(cond, msg)
Compile time assertion macro.
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.
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.
@ 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.
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
odp_feature_t not_used
Unused features.
128-bit unsigned integer structure
uint32_t u32[4]
128 bits as uint32_t words
uint64_t u64[2]
128 bits as uint64_t words
uint32_t fetch_max
Atomic fetch and maximum.
uint32_t bit_clr
Atomic bit clear.
uint32_t fetch_add
Atomic fetch and add.
uint32_t fetch_sub
Atomic fetch and subtract.
uint32_t xchg
Atomic exchange.
uint32_t bit_set
Atomic bit set.
struct odp_atomic_op_t::@6 op
Operation flags.
uint32_t sub
Atomic subtract.
uint32_t load
Atomic load.
uint32_t fetch_dec
Atomic fetch and decrement.
uint32_t fetch_inc
Atomic fetch and increment.
uint32_t inc
Atomic increment.
uint32_t bit_fetch_set
Atomic bit fetch and set.
uint32_t min
Atomic minimum.
uint32_t max
Atomic maximum.
uint32_t all_bits
All bits of the bit field structure.
uint32_t cas
Atomic compare and swap.
uint32_t store
Atomic store.
uint32_t fetch_min
Atomic fetch and minimum.
uint32_t dec
Atomic decrement.
uint32_t bit_fetch_clr
Atomic bit fetch and clear.
uint32_t tm
Traffic Manager APIs, e.g., odp_tm_xxx()
uint32_t stash
Stash APIs, e.g., odp_stash_xxx()
uint32_t crypto
Crypto APIs, e.g., odp_crypto_xxx()
uint32_t ipsec
IPsec APIs, e.g., odp_ipsec_xxx()
uint32_t timer
Timer APIs, e.g., odp_timer_xxx(), odp_timeout_xxx()
uint32_t cls
Classifier APIs, e.g., odp_cls_xxx(), odp_cos_xxx()
uint32_t schedule
Scheduler APIs, e.g., odp_schedule_xxx()
struct odp_feature_t::@148 feat
Individual feature bits.
uint32_t compress
Compression APIs, e.g., odp_comp_xxx()