Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/power/cpupower/bench/parse.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* cpufreq-bench CPUFreq microbenchmark
3
*
4
* Copyright (C) 2008 Christian Kornacker <[email protected]>
5
*/
6
7
#include <errno.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <stdarg.h>
11
#include <string.h>
12
#include <time.h>
13
#include <dirent.h>
14
15
#include <sys/utsname.h>
16
#include <sys/types.h>
17
#include <sys/stat.h>
18
19
#include "parse.h"
20
#include "config.h"
21
22
/**
23
* converts priority string to priority
24
*
25
* @param str string that represents a scheduler priority
26
*
27
* @retval priority
28
* @retval SCHED_ERR when the priority doesn't exit
29
**/
30
31
enum sched_prio string_to_prio(const char *str)
32
{
33
if (strncasecmp("high", str, strlen(str)) == 0)
34
return SCHED_HIGH;
35
else if (strncasecmp("default", str, strlen(str)) == 0)
36
return SCHED_DEFAULT;
37
else if (strncasecmp("low", str, strlen(str)) == 0)
38
return SCHED_LOW;
39
else
40
return SCHED_ERR;
41
}
42
43
/**
44
* create and open logfile
45
*
46
* @param dir directory in which the logfile should be created
47
*
48
* @retval logfile on success
49
* @retval NULL when the file can't be created
50
**/
51
52
FILE *prepare_output(const char *dirname)
53
{
54
FILE *output = NULL;
55
int len;
56
char *filename, *filename_tmp;
57
struct utsname sysdata;
58
DIR *dir;
59
60
dir = opendir(dirname);
61
if (dir == NULL) {
62
if (mkdir(dirname, 0755)) {
63
perror("mkdir");
64
fprintf(stderr, "error: Cannot create dir %s\n",
65
dirname);
66
return NULL;
67
}
68
}
69
70
len = strlen(dirname) + 30;
71
filename = malloc(sizeof(char) * len);
72
if (!filename) {
73
perror("malloc");
74
goto out_dir;
75
}
76
77
if (uname(&sysdata) == 0) {
78
len += strlen(sysdata.nodename) + strlen(sysdata.release);
79
filename_tmp = realloc(filename, sizeof(*filename) * len);
80
81
if (filename_tmp == NULL) {
82
free(filename);
83
perror("realloc");
84
goto out_dir;
85
}
86
87
filename = filename_tmp;
88
snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log",
89
dirname, sysdata.nodename, sysdata.release, time(NULL));
90
} else {
91
snprintf(filename, len - 1, "%s/benchmark_%li.log",
92
dirname, time(NULL));
93
}
94
95
dprintf("logfilename: %s\n", filename);
96
97
output = fopen(filename, "w+");
98
if (output == NULL) {
99
perror("fopen");
100
fprintf(stderr, "error: unable to open logfile\n");
101
goto out;
102
}
103
104
fprintf(stdout, "Logfile: %s\n", filename);
105
106
fprintf(output, "#round load sleep performance powersave percentage\n");
107
out:
108
free(filename);
109
out_dir:
110
closedir(dir);
111
return output;
112
}
113
114
/**
115
* returns the default config
116
*
117
* @retval default config on success
118
* @retval NULL when the output file can't be created
119
**/
120
121
struct config *prepare_default_config()
122
{
123
struct config *config = malloc(sizeof(struct config));
124
if (!config) {
125
perror("malloc");
126
return NULL;
127
}
128
129
dprintf("loading defaults\n");
130
131
config->sleep = 500000;
132
config->load = 500000;
133
config->sleep_step = 500000;
134
config->load_step = 500000;
135
config->cycles = 5;
136
config->rounds = 50;
137
config->cpu = 0;
138
config->prio = SCHED_HIGH;
139
config->verbose = 0;
140
strncpy(config->governor, "ondemand", sizeof(config->governor));
141
142
config->output = stdout;
143
144
#ifdef DEFAULT_CONFIG_FILE
145
if (prepare_config(DEFAULT_CONFIG_FILE, config))
146
return NULL;
147
#endif
148
return config;
149
}
150
151
/**
152
* parses config file and returns the config to the caller
153
*
154
* @param path config file name
155
*
156
* @retval 1 on error
157
* @retval 0 on success
158
**/
159
160
int prepare_config(const char *path, struct config *config)
161
{
162
size_t len = 0;
163
char opt[16], val[32], *line = NULL;
164
FILE *configfile;
165
166
if (config == NULL) {
167
fprintf(stderr, "error: config is NULL\n");
168
return 1;
169
}
170
171
configfile = fopen(path, "r");
172
if (configfile == NULL) {
173
fprintf(stderr, "error: unable to read configfile: %s, %s\n",
174
path, strerror(errno));
175
free(config);
176
return 1;
177
}
178
179
while (getline(&line, &len, configfile) != -1) {
180
if (line[0] == '#' || line[0] == ' ' || line[0] == '\n')
181
continue;
182
183
if (sscanf(line, "%14s = %30s", opt, val) < 2)
184
continue;
185
186
dprintf("parsing: %s -> %s\n", opt, val);
187
188
if (strcmp("sleep", opt) == 0)
189
sscanf(val, "%li", &config->sleep);
190
191
else if (strcmp("load", opt) == 0)
192
sscanf(val, "%li", &config->load);
193
194
else if (strcmp("load_step", opt) == 0)
195
sscanf(val, "%li", &config->load_step);
196
197
else if (strcmp("sleep_step", opt) == 0)
198
sscanf(val, "%li", &config->sleep_step);
199
200
else if (strcmp("cycles", opt) == 0)
201
sscanf(val, "%u", &config->cycles);
202
203
else if (strcmp("rounds", opt) == 0)
204
sscanf(val, "%u", &config->rounds);
205
206
else if (strcmp("verbose", opt) == 0)
207
sscanf(val, "%u", &config->verbose);
208
209
else if (strcmp("output", opt) == 0)
210
config->output = prepare_output(val);
211
212
else if (strcmp("cpu", opt) == 0)
213
sscanf(val, "%u", &config->cpu);
214
215
else if (strcmp("governor", opt) == 0) {
216
strncpy(config->governor, val,
217
sizeof(config->governor));
218
config->governor[sizeof(config->governor) - 1] = '\0';
219
}
220
221
else if (strcmp("priority", opt) == 0) {
222
if (string_to_prio(val) != SCHED_ERR)
223
config->prio = string_to_prio(val);
224
}
225
}
226
227
free(line);
228
229
return 0;
230
}
231
232