1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #pragma once |
3 | #include <stdlib.h> |
4 | #include <stdbool.h> |
5 | #include <linux/err.h> |
6 | #include <errno.h> |
7 | #include <unistd.h> |
8 | #include <bpf/bpf.h> |
9 | #include <bpf/libbpf.h> |
10 | #include <math.h> |
11 | #include <time.h> |
12 | #include <sys/syscall.h> |
13 | |
14 | struct cpu_set { |
15 | bool *cpus; |
16 | int cpus_len; |
17 | int next_cpu; |
18 | }; |
19 | |
20 | struct env { |
21 | char *bench_name; |
22 | int duration_sec; |
23 | int warmup_sec; |
24 | bool verbose; |
25 | bool list; |
26 | bool affinity; |
27 | bool quiet; |
28 | int consumer_cnt; |
29 | int producer_cnt; |
30 | int nr_cpus; |
31 | struct cpu_set prod_cpus; |
32 | struct cpu_set cons_cpus; |
33 | }; |
34 | |
35 | struct basic_stats { |
36 | double mean; |
37 | double stddev; |
38 | }; |
39 | |
40 | struct bench_res { |
41 | long hits; |
42 | long drops; |
43 | long false_hits; |
44 | long important_hits; |
45 | unsigned long gp_ns; |
46 | unsigned long gp_ct; |
47 | unsigned int stime; |
48 | }; |
49 | |
50 | struct bench { |
51 | const char *name; |
52 | const struct argp *argp; |
53 | void (*validate)(void); |
54 | void (*setup)(void); |
55 | void *(*producer_thread)(void *ctx); |
56 | void *(*consumer_thread)(void *ctx); |
57 | void (*measure)(struct bench_res* res); |
58 | void (*report_progress)(int iter, struct bench_res* res, long delta_ns); |
59 | void (*report_final)(struct bench_res res[], int res_cnt); |
60 | }; |
61 | |
62 | struct counter { |
63 | long value; |
64 | } __attribute__((aligned(128))); |
65 | |
66 | extern struct env env; |
67 | extern const struct bench *bench; |
68 | |
69 | void setup_libbpf(void); |
70 | void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns); |
71 | void hits_drops_report_final(struct bench_res res[], int res_cnt); |
72 | void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns); |
73 | void false_hits_report_final(struct bench_res res[], int res_cnt); |
74 | void ops_report_progress(int iter, struct bench_res *res, long delta_ns); |
75 | void ops_report_final(struct bench_res res[], int res_cnt); |
76 | void local_storage_report_progress(int iter, struct bench_res *res, |
77 | long delta_ns); |
78 | void local_storage_report_final(struct bench_res res[], int res_cnt); |
79 | void grace_period_latency_basic_stats(struct bench_res res[], int res_cnt, |
80 | struct basic_stats *gp_stat); |
81 | void grace_period_ticks_basic_stats(struct bench_res res[], int res_cnt, |
82 | struct basic_stats *gp_stat); |
83 | |
84 | static inline void atomic_inc(long *value) |
85 | { |
86 | (void)__atomic_add_fetch(value, 1, __ATOMIC_RELAXED); |
87 | } |
88 | |
89 | static inline void atomic_add(long *value, long n) |
90 | { |
91 | (void)__atomic_add_fetch(value, n, __ATOMIC_RELAXED); |
92 | } |
93 | |
94 | static inline long atomic_swap(long *value, long n) |
95 | { |
96 | return __atomic_exchange_n(value, n, __ATOMIC_RELAXED); |
97 | } |
98 | |