157 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 != 0) {54 fprintf(stderr, "strncmp benchmark doesn't support 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_measure(struct bench_res *res)132{133 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);134}135 136const struct bench bench_strncmp_no_helper = {137 .name = "strncmp-no-helper",138 .argp = &bench_strncmp_argp,139 .validate = strncmp_validate,140 .setup = strncmp_no_helper_setup,141 .producer_thread = strncmp_producer,142 .measure = strncmp_measure,143 .report_progress = hits_drops_report_progress,144 .report_final = hits_drops_report_final,145};146 147const struct bench bench_strncmp_helper = {148 .name = "strncmp-helper",149 .argp = &bench_strncmp_argp,150 .validate = strncmp_validate,151 .setup = strncmp_helper_setup,152 .producer_thread = strncmp_producer,153 .measure = strncmp_measure,154 .report_progress = hits_drops_report_progress,155 .report_final = hits_drops_report_final,156};157