0001
0002 #pragma once
0003 #include <stdlib.h>
0004 #include <stdbool.h>
0005 #include <linux/err.h>
0006 #include <errno.h>
0007 #include <unistd.h>
0008 #include <bpf/bpf.h>
0009 #include <bpf/libbpf.h>
0010 #include <math.h>
0011 #include <time.h>
0012 #include <sys/syscall.h>
0013
0014 struct cpu_set {
0015 bool *cpus;
0016 int cpus_len;
0017 int next_cpu;
0018 };
0019
0020 struct env {
0021 char *bench_name;
0022 int duration_sec;
0023 int warmup_sec;
0024 bool verbose;
0025 bool list;
0026 bool affinity;
0027 int consumer_cnt;
0028 int producer_cnt;
0029 struct cpu_set prod_cpus;
0030 struct cpu_set cons_cpus;
0031 };
0032
0033 struct basic_stats {
0034 double mean;
0035 double stddev;
0036 };
0037
0038 struct bench_res {
0039 long hits;
0040 long drops;
0041 long false_hits;
0042 long important_hits;
0043 unsigned long gp_ns;
0044 unsigned long gp_ct;
0045 unsigned int stime;
0046 };
0047
0048 struct bench {
0049 const char *name;
0050 void (*validate)(void);
0051 void (*setup)(void);
0052 void *(*producer_thread)(void *ctx);
0053 void *(*consumer_thread)(void *ctx);
0054 void (*measure)(struct bench_res* res);
0055 void (*report_progress)(int iter, struct bench_res* res, long delta_ns);
0056 void (*report_final)(struct bench_res res[], int res_cnt);
0057 };
0058
0059 struct counter {
0060 long value;
0061 } __attribute__((aligned(128)));
0062
0063 extern struct env env;
0064 extern const struct bench *bench;
0065
0066 void setup_libbpf(void);
0067 void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);
0068 void hits_drops_report_final(struct bench_res res[], int res_cnt);
0069 void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns);
0070 void false_hits_report_final(struct bench_res res[], int res_cnt);
0071 void ops_report_progress(int iter, struct bench_res *res, long delta_ns);
0072 void ops_report_final(struct bench_res res[], int res_cnt);
0073 void local_storage_report_progress(int iter, struct bench_res *res,
0074 long delta_ns);
0075 void local_storage_report_final(struct bench_res res[], int res_cnt);
0076 void grace_period_latency_basic_stats(struct bench_res res[], int res_cnt,
0077 struct basic_stats *gp_stat);
0078 void grace_period_ticks_basic_stats(struct bench_res res[], int res_cnt,
0079 struct basic_stats *gp_stat);
0080
0081 static inline __u64 get_time_ns(void)
0082 {
0083 struct timespec t;
0084
0085 clock_gettime(CLOCK_MONOTONIC, &t);
0086
0087 return (u64)t.tv_sec * 1000000000 + t.tv_nsec;
0088 }
0089
0090 static inline void atomic_inc(long *value)
0091 {
0092 (void)__atomic_add_fetch(value, 1, __ATOMIC_RELAXED);
0093 }
0094
0095 static inline void atomic_add(long *value, long n)
0096 {
0097 (void)__atomic_add_fetch(value, n, __ATOMIC_RELAXED);
0098 }
0099
0100 static inline long atomic_swap(long *value, long n)
0101 {
0102 return __atomic_exchange_n(value, n, __ATOMIC_RELAXED);
0103 }