1 /* 2 * 3 * builtin-bench.c 4 * 5 * General benchmarking subsystem provided by perf 6 * 7 * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> 8 * 9 */ 10 11 /* 12 * 13 * Available subsystem list: 14 * sched ... scheduler and IPC mechanism 15 * 16 */ 17 18 #include "perf.h" 19 #include "util/util.h" 20 #include "util/parse-options.h" 21 #include "builtin.h" 22 #include "bench/bench.h" 23 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 28 struct bench_suite { 29 const char *name; 30 const char *summary; 31 int (*fn)(int, const char **, const char *); 32 }; 33 34 static struct bench_suite sched_suites[] = { 35 { "messaging", 36 "Benchmark for scheduler and IPC mechanisms", 37 bench_sched_messaging }, 38 { "pipe", 39 "Flood of communication over pipe() between two processes", 40 bench_sched_pipe }, 41 { NULL, 42 NULL, 43 NULL } 44 }; 45 46 struct bench_subsys { 47 const char *name; 48 const char *summary; 49 struct bench_suite *suites; 50 }; 51 52 static struct bench_subsys subsystems[] = { 53 { "sched", 54 "scheduler and IPC mechanism", 55 sched_suites }, 56 { NULL, 57 NULL, 58 NULL } 59 }; 60 61 static void dump_suites(int subsys_index) 62 { 63 int i; 64 65 printf("List of available suites for %s...\n\n", 66 subsystems[subsys_index].name); 67 68 for (i = 0; subsystems[subsys_index].suites[i].name; i++) 69 printf("\t%s: %s\n", 70 subsystems[subsys_index].suites[i].name, 71 subsystems[subsys_index].suites[i].summary); 72 73 printf("\n"); 74 return; 75 } 76 77 static char *bench_format_str; 78 int bench_format = BENCH_FORMAT_DEFAULT; 79 80 static const struct option bench_options[] = { 81 OPT_STRING('f', "format", &bench_format_str, "default", 82 "Specify format style"), 83 OPT_END() 84 }; 85 86 static const char * const bench_usage[] = { 87 "perf bench [<common options>] <subsystem> <suite> [<options>]", 88 NULL 89 }; 90 91 static void print_usage(void) 92 { 93 int i; 94 95 printf("Usage: \n"); 96 for (i = 0; bench_usage[i]; i++) 97 printf("\t%s\n", bench_usage[i]); 98 printf("\n"); 99 100 printf("List of available subsystems...\n\n"); 101 102 for (i = 0; subsystems[i].name; i++) 103 printf("\t%s: %s\n", 104 subsystems[i].name, subsystems[i].summary); 105 printf("\n"); 106 } 107 108 static int bench_str2int(char *str) 109 { 110 if (!str) 111 return BENCH_FORMAT_DEFAULT; 112 113 if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR)) 114 return BENCH_FORMAT_DEFAULT; 115 else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR)) 116 return BENCH_FORMAT_SIMPLE; 117 118 return BENCH_FORMAT_UNKNOWN; 119 } 120 121 int cmd_bench(int argc, const char **argv, const char *prefix __used) 122 { 123 int i, j, status = 0; 124 125 if (argc < 2) { 126 /* No subsystem specified. */ 127 print_usage(); 128 goto end; 129 } 130 131 argc = parse_options(argc, argv, bench_options, bench_usage, 132 PARSE_OPT_STOP_AT_NON_OPTION); 133 134 bench_format = bench_str2int(bench_format_str); 135 if (bench_format == BENCH_FORMAT_UNKNOWN) { 136 printf("Unknown format descriptor:%s\n", bench_format_str); 137 goto end; 138 } 139 140 if (argc < 1) { 141 print_usage(); 142 goto end; 143 } 144 145 for (i = 0; subsystems[i].name; i++) { 146 if (strcmp(subsystems[i].name, argv[0])) 147 continue; 148 149 if (argc < 2) { 150 /* No suite specified. */ 151 dump_suites(i); 152 goto end; 153 } 154 155 for (j = 0; subsystems[i].suites[j].name; j++) { 156 if (strcmp(subsystems[i].suites[j].name, argv[1])) 157 continue; 158 159 if (bench_format == BENCH_FORMAT_DEFAULT) 160 printf("# Running %s/%s benchmark...\n", 161 subsystems[i].name, 162 subsystems[i].suites[j].name); 163 status = subsystems[i].suites[j].fn(argc - 1, 164 argv + 1, prefix); 165 goto end; 166 } 167 168 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 169 dump_suites(i); 170 goto end; 171 } 172 173 printf("Unknown suite:%s for %s\n", argv[1], argv[0]); 174 status = 1; 175 goto end; 176 } 177 178 printf("Unknown subsystem:%s\n", argv[0]); 179 status = 1; 180 181 end: 182 return status; 183 } 184