Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 2021. Huawei Technologies Co., Ltd */
0003 #include <argp.h>
0004 #include "bench.h"
0005 #include "strncmp_bench.skel.h"
0006 
0007 static struct strncmp_ctx {
0008     struct strncmp_bench *skel;
0009 } ctx;
0010 
0011 static struct strncmp_args {
0012     u32 cmp_str_len;
0013 } args = {
0014     .cmp_str_len = 32,
0015 };
0016 
0017 enum {
0018     ARG_CMP_STR_LEN = 5000,
0019 };
0020 
0021 static const struct argp_option opts[] = {
0022     { "cmp-str-len", ARG_CMP_STR_LEN, "CMP_STR_LEN", 0,
0023       "Set the length of compared string" },
0024     {},
0025 };
0026 
0027 static error_t strncmp_parse_arg(int key, char *arg, struct argp_state *state)
0028 {
0029     switch (key) {
0030     case ARG_CMP_STR_LEN:
0031         args.cmp_str_len = strtoul(arg, NULL, 10);
0032         if (!args.cmp_str_len ||
0033             args.cmp_str_len >= sizeof(ctx.skel->bss->str)) {
0034             fprintf(stderr, "Invalid cmp str len (limit %zu)\n",
0035                 sizeof(ctx.skel->bss->str));
0036             argp_usage(state);
0037         }
0038         break;
0039     default:
0040         return ARGP_ERR_UNKNOWN;
0041     }
0042 
0043     return 0;
0044 }
0045 
0046 const struct argp bench_strncmp_argp = {
0047     .options = opts,
0048     .parser = strncmp_parse_arg,
0049 };
0050 
0051 static void strncmp_validate(void)
0052 {
0053     if (env.consumer_cnt != 1) {
0054         fprintf(stderr, "strncmp benchmark doesn't support multi-consumer!\n");
0055         exit(1);
0056     }
0057 }
0058 
0059 static void strncmp_setup(void)
0060 {
0061     int err;
0062     char *target;
0063     size_t i, sz;
0064 
0065     sz = sizeof(ctx.skel->rodata->target);
0066     if (!sz || sz < sizeof(ctx.skel->bss->str)) {
0067         fprintf(stderr, "invalid string size (target %zu, src %zu)\n",
0068             sz, sizeof(ctx.skel->bss->str));
0069         exit(1);
0070     }
0071 
0072     setup_libbpf();
0073 
0074     ctx.skel = strncmp_bench__open();
0075     if (!ctx.skel) {
0076         fprintf(stderr, "failed to open skeleton\n");
0077         exit(1);
0078     }
0079 
0080     srandom(time(NULL));
0081     target = ctx.skel->rodata->target;
0082     for (i = 0; i < sz - 1; i++)
0083         target[i] = '1' + random() % 9;
0084     target[sz - 1] = '\0';
0085 
0086     ctx.skel->rodata->cmp_str_len = args.cmp_str_len;
0087 
0088     memcpy(ctx.skel->bss->str, target, args.cmp_str_len);
0089     ctx.skel->bss->str[args.cmp_str_len] = '\0';
0090     /* Make bss->str < rodata->target */
0091     ctx.skel->bss->str[args.cmp_str_len - 1] -= 1;
0092 
0093     err = strncmp_bench__load(ctx.skel);
0094     if (err) {
0095         fprintf(stderr, "failed to load skeleton\n");
0096         strncmp_bench__destroy(ctx.skel);
0097         exit(1);
0098     }
0099 }
0100 
0101 static void strncmp_attach_prog(struct bpf_program *prog)
0102 {
0103     struct bpf_link *link;
0104 
0105     link = bpf_program__attach(prog);
0106     if (!link) {
0107         fprintf(stderr, "failed to attach program!\n");
0108         exit(1);
0109     }
0110 }
0111 
0112 static void strncmp_no_helper_setup(void)
0113 {
0114     strncmp_setup();
0115     strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper);
0116 }
0117 
0118 static void strncmp_helper_setup(void)
0119 {
0120     strncmp_setup();
0121     strncmp_attach_prog(ctx.skel->progs.strncmp_helper);
0122 }
0123 
0124 static void *strncmp_producer(void *ctx)
0125 {
0126     while (true)
0127         (void)syscall(__NR_getpgid);
0128     return NULL;
0129 }
0130 
0131 static void *strncmp_consumer(void *ctx)
0132 {
0133     return NULL;
0134 }
0135 
0136 static void strncmp_measure(struct bench_res *res)
0137 {
0138     res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
0139 }
0140 
0141 const struct bench bench_strncmp_no_helper = {
0142     .name = "strncmp-no-helper",
0143     .validate = strncmp_validate,
0144     .setup = strncmp_no_helper_setup,
0145     .producer_thread = strncmp_producer,
0146     .consumer_thread = strncmp_consumer,
0147     .measure = strncmp_measure,
0148     .report_progress = hits_drops_report_progress,
0149     .report_final = hits_drops_report_final,
0150 };
0151 
0152 const struct bench bench_strncmp_helper = {
0153     .name = "strncmp-helper",
0154     .validate = strncmp_validate,
0155     .setup = strncmp_helper_setup,
0156     .producer_thread = strncmp_producer,
0157     .consumer_thread = strncmp_consumer,
0158     .measure = strncmp_measure,
0159     .report_progress = hits_drops_report_progress,
0160     .report_final = hits_drops_report_final,
0161 };