bench_strncmp.c (3504B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (C) 2021. Huawei Technologies Co., Ltd */ 3#include <argp.h> 4#include "bench.h" 5#include "strncmp_bench.skel.h" 6 7static struct strncmp_ctx { 8 struct strncmp_bench *skel; 9} ctx; 10 11static struct strncmp_args { 12 u32 cmp_str_len; 13} args = { 14 .cmp_str_len = 32, 15}; 16 17enum { 18 ARG_CMP_STR_LEN = 5000, 19}; 20 21static const struct argp_option opts[] = { 22 { "cmp-str-len", ARG_CMP_STR_LEN, "CMP_STR_LEN", 0, 23 "Set the length of compared string" }, 24 {}, 25}; 26 27static error_t strncmp_parse_arg(int key, char *arg, struct argp_state *state) 28{ 29 switch (key) { 30 case ARG_CMP_STR_LEN: 31 args.cmp_str_len = strtoul(arg, NULL, 10); 32 if (!args.cmp_str_len || 33 args.cmp_str_len >= sizeof(ctx.skel->bss->str)) { 34 fprintf(stderr, "Invalid cmp str len (limit %zu)\n", 35 sizeof(ctx.skel->bss->str)); 36 argp_usage(state); 37 } 38 break; 39 default: 40 return ARGP_ERR_UNKNOWN; 41 } 42 43 return 0; 44} 45 46const struct argp bench_strncmp_argp = { 47 .options = opts, 48 .parser = strncmp_parse_arg, 49}; 50 51static void strncmp_validate(void) 52{ 53 if (env.consumer_cnt != 1) { 54 fprintf(stderr, "strncmp benchmark doesn't support multi-consumer!\n"); 55 exit(1); 56 } 57} 58 59static void strncmp_setup(void) 60{ 61 int err; 62 char *target; 63 size_t i, sz; 64 65 sz = sizeof(ctx.skel->rodata->target); 66 if (!sz || sz < sizeof(ctx.skel->bss->str)) { 67 fprintf(stderr, "invalid string size (target %zu, src %zu)\n", 68 sz, sizeof(ctx.skel->bss->str)); 69 exit(1); 70 } 71 72 setup_libbpf(); 73 74 ctx.skel = strncmp_bench__open(); 75 if (!ctx.skel) { 76 fprintf(stderr, "failed to open skeleton\n"); 77 exit(1); 78 } 79 80 srandom(time(NULL)); 81 target = ctx.skel->rodata->target; 82 for (i = 0; i < sz - 1; i++) 83 target[i] = '1' + random() % 9; 84 target[sz - 1] = '\0'; 85 86 ctx.skel->rodata->cmp_str_len = args.cmp_str_len; 87 88 memcpy(ctx.skel->bss->str, target, args.cmp_str_len); 89 ctx.skel->bss->str[args.cmp_str_len] = '\0'; 90 /* Make bss->str < rodata->target */ 91 ctx.skel->bss->str[args.cmp_str_len - 1] -= 1; 92 93 err = strncmp_bench__load(ctx.skel); 94 if (err) { 95 fprintf(stderr, "failed to load skeleton\n"); 96 strncmp_bench__destroy(ctx.skel); 97 exit(1); 98 } 99} 100 101static void strncmp_attach_prog(struct bpf_program *prog) 102{ 103 struct bpf_link *link; 104 105 link = bpf_program__attach(prog); 106 if (!link) { 107 fprintf(stderr, "failed to attach program!\n"); 108 exit(1); 109 } 110} 111 112static void strncmp_no_helper_setup(void) 113{ 114 strncmp_setup(); 115 strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper); 116} 117 118static void strncmp_helper_setup(void) 119{ 120 strncmp_setup(); 121 strncmp_attach_prog(ctx.skel->progs.strncmp_helper); 122} 123 124static void *strncmp_producer(void *ctx) 125{ 126 while (true) 127 (void)syscall(__NR_getpgid); 128 return NULL; 129} 130 131static void *strncmp_consumer(void *ctx) 132{ 133 return NULL; 134} 135 136static void strncmp_measure(struct bench_res *res) 137{ 138 res->hits = atomic_swap(&ctx.skel->bss->hits, 0); 139} 140 141const struct bench bench_strncmp_no_helper = { 142 .name = "strncmp-no-helper", 143 .validate = strncmp_validate, 144 .setup = strncmp_no_helper_setup, 145 .producer_thread = strncmp_producer, 146 .consumer_thread = strncmp_consumer, 147 .measure = strncmp_measure, 148 .report_progress = hits_drops_report_progress, 149 .report_final = hits_drops_report_final, 150}; 151 152const struct bench bench_strncmp_helper = { 153 .name = "strncmp-helper", 154 .validate = strncmp_validate, 155 .setup = strncmp_helper_setup, 156 .producer_thread = strncmp_producer, 157 .consumer_thread = strncmp_consumer, 158 .measure = strncmp_measure, 159 .report_progress = hits_drops_report_progress, 160 .report_final = hits_drops_report_final, 161};