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