aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power/cpupower/bench/parse.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2011-03-30 10:30:11 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2011-07-29 12:35:36 -0400
commit7fe2f6399a84760a9af8896ac152728250f82adb (patch)
treefa4bf236359b8d6d9f8d6ff823ddd3e839da5768 /tools/power/cpupower/bench/parse.c
parent02f8c6aee8df3cdc935e9bdd4f2d020306035dbe (diff)
cpupowerutils - cpufrequtils extended with quite some features
CPU power consumption vs performance tuning is no longer limited to CPU frequency switching anymore: deep sleep states, traditional dynamic frequency scaling and hidden turbo/boost frequencies are tied close together and depend on each other. The first two exist on different architectures like PPC, Itanium and ARM, the latter (so far) only on X86. On X86 the APU (CPU+GPU) will only run most efficiently if CPU and GPU has proper power management in place. Users and Developers want to have *one* tool to get an overview what their system supports and to monitor and debug CPU power management in detail. The tool should compile and work on as many architectures as possible. Once this tool stabilizes a bit, it is intended to replace the Intel-specific tools in tools/power/x86 Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'tools/power/cpupower/bench/parse.c')
-rw-r--r--tools/power/cpupower/bench/parse.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c
new file mode 100644
index 00000000000..3b270ac92c4
--- /dev/null
+++ b/tools/power/cpupower/bench/parse.c
@@ -0,0 +1,224 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24#include <time.h>
25#include <dirent.h>
26
27#include <sys/utsname.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "parse.h"
32#include "config.h"
33
34/**
35 * converts priority string to priority
36 *
37 * @param str string that represents a scheduler priority
38 *
39 * @retval priority
40 * @retval SCHED_ERR when the priority doesn't exit
41 **/
42
43enum sched_prio string_to_prio(const char *str)
44{
45 if (strncasecmp("high", str, strlen(str)) == 0)
46 return SCHED_HIGH;
47 else if (strncasecmp("default", str, strlen(str)) == 0)
48 return SCHED_DEFAULT;
49 else if (strncasecmp("low", str, strlen(str)) == 0)
50 return SCHED_LOW;
51 else
52 return SCHED_ERR;
53}
54
55/**
56 * create and open logfile
57 *
58 * @param dir directory in which the logfile should be created
59 *
60 * @retval logfile on success
61 * @retval NULL when the file can't be created
62 **/
63
64FILE *prepare_output(const char *dirname)
65{
66 FILE *output = NULL;
67 int len;
68 char *filename;
69 struct utsname sysdata;
70 DIR *dir;
71
72 dir = opendir(dirname);
73 if (dir == NULL) {
74 if (mkdir(dirname, 0755)) {
75 perror("mkdir");
76 fprintf(stderr, "error: Cannot create dir %s\n",
77 dirname);
78 return NULL;
79 }
80 }
81
82 len = strlen(dirname) + 30;
83 filename = malloc(sizeof(char) * len);
84
85 if (uname(&sysdata) == 0) {
86 len += strlen(sysdata.nodename) + strlen(sysdata.release);
87 filename = realloc(filename, sizeof(char) * len);
88
89 if(filename == NULL) {
90 perror("realloc");
91 return NULL;
92 }
93
94 snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log",
95 dirname, sysdata.nodename, sysdata.release, time(NULL));
96 } else {
97 snprintf(filename, len -1, "%s/benchmark_%li.log", dirname, time(NULL));
98 }
99
100 dprintf("logilename: %s\n", filename);
101
102 if ((output = fopen(filename, "w+")) == NULL) {
103 perror("fopen");
104 fprintf(stderr, "error: unable to open logfile\n");
105 }
106
107 fprintf(stdout, "Logfile: %s\n", filename);
108
109 free(filename);
110 fprintf(output, "#round load sleep performance powersave percentage\n");
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
121struct config *prepare_default_config()
122{
123 struct config *config = malloc(sizeof(struct config));
124
125 dprintf("loading defaults\n");
126
127 config->sleep = 500000;
128 config->load = 500000;
129 config->sleep_step = 500000;
130 config->load_step = 500000;
131 config->cycles = 5;
132 config->rounds = 50;
133 config->cpu = 0;
134 config->prio = SCHED_HIGH;
135 config->verbose = 0;
136 strncpy(config->governor, "ondemand", 8);
137
138 config->output = stdout;
139
140#ifdef DEFAULT_CONFIG_FILE
141 if (prepare_config(DEFAULT_CONFIG_FILE, config))
142 return NULL;
143#endif
144 return config;
145}
146
147/**
148 * parses config file and returns the config to the caller
149 *
150 * @param path config file name
151 *
152 * @retval 1 on error
153 * @retval 0 on success
154 **/
155
156int prepare_config(const char *path, struct config *config)
157{
158 size_t len = 0;
159 char *opt, *val, *line = NULL;
160 FILE *configfile = fopen(path, "r");
161
162 if (config == NULL) {
163 fprintf(stderr, "error: config is NULL\n");
164 return 1;
165 }
166
167 if (configfile == NULL) {
168 perror("fopen");
169 fprintf(stderr, "error: unable to read configfile\n");
170 free(config);
171 return 1;
172 }
173
174 while (getline(&line, &len, configfile) != -1)
175 {
176 if (line[0] == '#' || line[0] == ' ')
177 continue;
178
179 sscanf(line, "%as = %as", &opt, &val);
180
181 dprintf("parsing: %s -> %s\n", opt, val);
182
183 if (strncmp("sleep", opt, strlen(opt)) == 0)
184 sscanf(val, "%li", &config->sleep);
185
186 else if (strncmp("load", opt, strlen(opt)) == 0)
187 sscanf(val, "%li", &config->load);
188
189 else if (strncmp("load_step", opt, strlen(opt)) == 0)
190 sscanf(val, "%li", &config->load_step);
191
192 else if (strncmp("sleep_step", opt, strlen(opt)) == 0)
193 sscanf(val, "%li", &config->sleep_step);
194
195 else if (strncmp("cycles", opt, strlen(opt)) == 0)
196 sscanf(val, "%u", &config->cycles);
197
198 else if (strncmp("rounds", opt, strlen(opt)) == 0)
199 sscanf(val, "%u", &config->rounds);
200
201 else if (strncmp("verbose", opt, strlen(opt)) == 0)
202 sscanf(val, "%u", &config->verbose);
203
204 else if (strncmp("output", opt, strlen(opt)) == 0)
205 config->output = prepare_output(val);
206
207 else if (strncmp("cpu", opt, strlen(opt)) == 0)
208 sscanf(val, "%u", &config->cpu);
209
210 else if (strncmp("governor", opt, 14) == 0)
211 strncpy(config->governor, val, 14);
212
213 else if (strncmp("priority", opt, strlen(opt)) == 0) {
214 if (string_to_prio(val) != SCHED_ERR)
215 config->prio = string_to_prio(val);
216 }
217 }
218
219 free(line);
220 free(opt);
221 free(val);
222
223 return 0;
224}