|  | /* SPDX-License-Identifier: GPL-2.0 */ | 
|  | #pragma once | 
|  | #include <stdlib.h> | 
|  | #include <stdbool.h> | 
|  | #include <linux/err.h> | 
|  | #include <errno.h> | 
|  | #include <unistd.h> | 
|  | #include <bpf/bpf.h> | 
|  | #include <bpf/libbpf.h> | 
|  | #include <math.h> | 
|  | #include <time.h> | 
|  | #include <sys/syscall.h> | 
|  |  | 
|  | struct cpu_set { | 
|  | bool *cpus; | 
|  | int cpus_len; | 
|  | int next_cpu; | 
|  | }; | 
|  |  | 
|  | struct env { | 
|  | char *bench_name; | 
|  | int duration_sec; | 
|  | int warmup_sec; | 
|  | bool verbose; | 
|  | bool list; | 
|  | bool affinity; | 
|  | int consumer_cnt; | 
|  | int producer_cnt; | 
|  | struct cpu_set prod_cpus; | 
|  | struct cpu_set cons_cpus; | 
|  | }; | 
|  |  | 
|  | struct bench_res { | 
|  | long hits; | 
|  | long drops; | 
|  | }; | 
|  |  | 
|  | struct bench { | 
|  | const char *name; | 
|  | void (*validate)(); | 
|  | void (*setup)(); | 
|  | void *(*producer_thread)(void *ctx); | 
|  | void *(*consumer_thread)(void *ctx); | 
|  | void (*measure)(struct bench_res* res); | 
|  | void (*report_progress)(int iter, struct bench_res* res, long delta_ns); | 
|  | void (*report_final)(struct bench_res res[], int res_cnt); | 
|  | }; | 
|  |  | 
|  | struct counter { | 
|  | long value; | 
|  | } __attribute__((aligned(128))); | 
|  |  | 
|  | extern struct env env; | 
|  | extern const struct bench *bench; | 
|  |  | 
|  | void setup_libbpf(); | 
|  | void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns); | 
|  | void hits_drops_report_final(struct bench_res res[], int res_cnt); | 
|  |  | 
|  | static inline __u64 get_time_ns() { | 
|  | struct timespec t; | 
|  |  | 
|  | clock_gettime(CLOCK_MONOTONIC, &t); | 
|  |  | 
|  | return (u64)t.tv_sec * 1000000000 + t.tv_nsec; | 
|  | } | 
|  |  | 
|  | static inline void atomic_inc(long *value) | 
|  | { | 
|  | (void)__atomic_add_fetch(value, 1, __ATOMIC_RELAXED); | 
|  | } | 
|  |  | 
|  | static inline void atomic_add(long *value, long n) | 
|  | { | 
|  | (void)__atomic_add_fetch(value, n, __ATOMIC_RELAXED); | 
|  | } | 
|  |  | 
|  | static inline long atomic_swap(long *value, long n) | 
|  | { | 
|  | return __atomic_exchange_n(value, n, __ATOMIC_RELAXED); | 
|  | } |