1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #pragma once
3*4882a593Smuzhiyun #include <stdlib.h>
4*4882a593Smuzhiyun #include <stdbool.h>
5*4882a593Smuzhiyun #include <linux/err.h>
6*4882a593Smuzhiyun #include <errno.h>
7*4882a593Smuzhiyun #include <unistd.h>
8*4882a593Smuzhiyun #include <bpf/bpf.h>
9*4882a593Smuzhiyun #include <bpf/libbpf.h>
10*4882a593Smuzhiyun #include <math.h>
11*4882a593Smuzhiyun #include <time.h>
12*4882a593Smuzhiyun #include <sys/syscall.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun struct cpu_set {
15*4882a593Smuzhiyun bool *cpus;
16*4882a593Smuzhiyun int cpus_len;
17*4882a593Smuzhiyun int next_cpu;
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun struct env {
21*4882a593Smuzhiyun char *bench_name;
22*4882a593Smuzhiyun int duration_sec;
23*4882a593Smuzhiyun int warmup_sec;
24*4882a593Smuzhiyun bool verbose;
25*4882a593Smuzhiyun bool list;
26*4882a593Smuzhiyun bool affinity;
27*4882a593Smuzhiyun int consumer_cnt;
28*4882a593Smuzhiyun int producer_cnt;
29*4882a593Smuzhiyun struct cpu_set prod_cpus;
30*4882a593Smuzhiyun struct cpu_set cons_cpus;
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun struct bench_res {
34*4882a593Smuzhiyun long hits;
35*4882a593Smuzhiyun long drops;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun struct bench {
39*4882a593Smuzhiyun const char *name;
40*4882a593Smuzhiyun void (*validate)();
41*4882a593Smuzhiyun void (*setup)();
42*4882a593Smuzhiyun void *(*producer_thread)(void *ctx);
43*4882a593Smuzhiyun void *(*consumer_thread)(void *ctx);
44*4882a593Smuzhiyun void (*measure)(struct bench_res* res);
45*4882a593Smuzhiyun void (*report_progress)(int iter, struct bench_res* res, long delta_ns);
46*4882a593Smuzhiyun void (*report_final)(struct bench_res res[], int res_cnt);
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun struct counter {
50*4882a593Smuzhiyun long value;
51*4882a593Smuzhiyun } __attribute__((aligned(128)));
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun extern struct env env;
54*4882a593Smuzhiyun extern const struct bench *bench;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun void setup_libbpf();
57*4882a593Smuzhiyun void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);
58*4882a593Smuzhiyun void hits_drops_report_final(struct bench_res res[], int res_cnt);
59*4882a593Smuzhiyun
get_time_ns()60*4882a593Smuzhiyun static inline __u64 get_time_ns() {
61*4882a593Smuzhiyun struct timespec t;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun clock_gettime(CLOCK_MONOTONIC, &t);
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun return (u64)t.tv_sec * 1000000000 + t.tv_nsec;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
atomic_inc(long * value)68*4882a593Smuzhiyun static inline void atomic_inc(long *value)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun (void)__atomic_add_fetch(value, 1, __ATOMIC_RELAXED);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
atomic_add(long * value,long n)73*4882a593Smuzhiyun static inline void atomic_add(long *value, long n)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun (void)__atomic_add_fetch(value, n, __ATOMIC_RELAXED);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
atomic_swap(long * value,long n)78*4882a593Smuzhiyun static inline long atomic_swap(long *value, long n)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun return __atomic_exchange_n(value, n, __ATOMIC_RELAXED);
81*4882a593Smuzhiyun }
82