1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* cpufreq-bench CPUFreq microbenchmark |
3 | * |
4 | * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> |
5 | */ |
6 | |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <string.h> |
10 | #include <unistd.h> |
11 | #include <getopt.h> |
12 | #include <errno.h> |
13 | |
14 | #include "config.h" |
15 | #include "system.h" |
16 | #include "benchmark.h" |
17 | |
18 | static struct option long_options[] = { |
19 | {"output" , 1, 0, 'o'}, |
20 | {"sleep" , 1, 0, 's'}, |
21 | {"load" , 1, 0, 'l'}, |
22 | {"verbose" , 0, 0, 'v'}, |
23 | {"cpu" , 1, 0, 'c'}, |
24 | {"governor" , 1, 0, 'g'}, |
25 | {"prio" , 1, 0, 'p'}, |
26 | {"file" , 1, 0, 'f'}, |
27 | {"cycles" , 1, 0, 'n'}, |
28 | {"rounds" , 1, 0, 'r'}, |
29 | {"load-step" , 1, 0, 'x'}, |
30 | {"sleep-step" , 1, 0, 'y'}, |
31 | {"help" , 0, 0, 'h'}, |
32 | {0, 0, 0, 0} |
33 | }; |
34 | |
35 | /******************************************************************* |
36 | usage |
37 | *******************************************************************/ |
38 | |
39 | void usage() |
40 | { |
41 | printf("usage: ./bench\n" ); |
42 | printf("Options:\n" ); |
43 | printf(" -l, --load=<long int>\t\tinitial load time in us\n" ); |
44 | printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n" ); |
45 | printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n" ); |
46 | printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n" ); |
47 | printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n" ); |
48 | printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n" ); |
49 | printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n" ); |
50 | printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n" ); |
51 | printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n" ); |
52 | printf(" -f, --file=<configfile>\t\tconfig file to use\n" ); |
53 | printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n" ); |
54 | printf(" -v, --verbose\t\t\t\tverbose output on/off\n" ); |
55 | printf(" -h, --help\t\t\t\tPrint this help screen\n" ); |
56 | exit(1); |
57 | } |
58 | |
59 | /******************************************************************* |
60 | main |
61 | *******************************************************************/ |
62 | |
63 | int main(int argc, char **argv) |
64 | { |
65 | int c; |
66 | int option_index = 0; |
67 | struct config *config = NULL; |
68 | |
69 | config = prepare_default_config(); |
70 | |
71 | if (config == NULL) |
72 | return EXIT_FAILURE; |
73 | |
74 | while (1) { |
75 | c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:" , |
76 | long_options, &option_index); |
77 | if (c == -1) |
78 | break; |
79 | |
80 | switch (c) { |
81 | case 'o': |
82 | if (config->output != NULL) |
83 | fclose(config->output); |
84 | |
85 | config->output = prepare_output(optarg); |
86 | |
87 | if (config->output == NULL) |
88 | return EXIT_FAILURE; |
89 | |
90 | dprintf("user output path -> %s\n" , optarg); |
91 | break; |
92 | case 's': |
93 | sscanf(optarg, "%li" , &config->sleep); |
94 | dprintf("user sleep time -> %s\n" , optarg); |
95 | break; |
96 | case 'l': |
97 | sscanf(optarg, "%li" , &config->load); |
98 | dprintf("user load time -> %s\n" , optarg); |
99 | break; |
100 | case 'c': |
101 | sscanf(optarg, "%u" , &config->cpu); |
102 | dprintf("user cpu -> %s\n" , optarg); |
103 | break; |
104 | case 'g': |
105 | strncpy(config->governor, optarg, 14); |
106 | dprintf("user governor -> %s\n" , optarg); |
107 | break; |
108 | case 'p': |
109 | if (string_to_prio(str: optarg) != SCHED_ERR) { |
110 | config->prio = string_to_prio(str: optarg); |
111 | dprintf("user prio -> %s\n" , optarg); |
112 | } else { |
113 | if (config != NULL) { |
114 | if (config->output != NULL) |
115 | fclose(config->output); |
116 | free(config); |
117 | } |
118 | usage(); |
119 | } |
120 | break; |
121 | case 'n': |
122 | sscanf(optarg, "%u" , &config->cycles); |
123 | dprintf("user cycles -> %s\n" , optarg); |
124 | break; |
125 | case 'r': |
126 | sscanf(optarg, "%u" , &config->rounds); |
127 | dprintf("user rounds -> %s\n" , optarg); |
128 | break; |
129 | case 'x': |
130 | sscanf(optarg, "%li" , &config->load_step); |
131 | dprintf("user load_step -> %s\n" , optarg); |
132 | break; |
133 | case 'y': |
134 | sscanf(optarg, "%li" , &config->sleep_step); |
135 | dprintf("user sleep_step -> %s\n" , optarg); |
136 | break; |
137 | case 'f': |
138 | if (prepare_config(path: optarg, config)) |
139 | return EXIT_FAILURE; |
140 | break; |
141 | case 'v': |
142 | config->verbose = 1; |
143 | dprintf("verbose output enabled\n" ); |
144 | break; |
145 | case 'h': |
146 | case '?': |
147 | default: |
148 | if (config != NULL) { |
149 | if (config->output != NULL) |
150 | fclose(config->output); |
151 | free(config); |
152 | } |
153 | usage(); |
154 | } |
155 | } |
156 | |
157 | if (config->verbose) { |
158 | printf("starting benchmark with parameters:\n" ); |
159 | printf("config:\n\t" |
160 | "sleep=%li\n\t" |
161 | "load=%li\n\t" |
162 | "sleep_step=%li\n\t" |
163 | "load_step=%li\n\t" |
164 | "cpu=%u\n\t" |
165 | "cycles=%u\n\t" |
166 | "rounds=%u\n\t" |
167 | "governor=%s\n\n" , |
168 | config->sleep, |
169 | config->load, |
170 | config->sleep_step, |
171 | config->load_step, |
172 | config->cpu, |
173 | config->cycles, |
174 | config->rounds, |
175 | config->governor); |
176 | } |
177 | |
178 | prepare_user(config); |
179 | prepare_system(config); |
180 | start_benchmark(config); |
181 | |
182 | if (config->output != stdout) |
183 | fclose(config->output); |
184 | |
185 | free(config); |
186 | |
187 | return EXIT_SUCCESS; |
188 | } |
189 | |
190 | |