17fe2f639SDominik Brodowski /* cpufreq-bench CPUFreq microbenchmark 27fe2f639SDominik Brodowski * 37fe2f639SDominik Brodowski * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> 47fe2f639SDominik Brodowski * 57fe2f639SDominik Brodowski * This program is free software; you can redistribute it and/or modify 67fe2f639SDominik Brodowski * it under the terms of the GNU General Public License as published by 77fe2f639SDominik Brodowski * the Free Software Foundation; either version 2 of the License, or 87fe2f639SDominik Brodowski * (at your option) any later version. 97fe2f639SDominik Brodowski * 107fe2f639SDominik Brodowski * This program is distributed in the hope that it will be useful, 117fe2f639SDominik Brodowski * but WITHOUT ANY WARRANTY; without even the implied warranty of 127fe2f639SDominik Brodowski * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 137fe2f639SDominik Brodowski * GNU General Public License for more details. 147fe2f639SDominik Brodowski * 157fe2f639SDominik Brodowski * You should have received a copy of the GNU General Public License 167fe2f639SDominik Brodowski * along with this program; if not, write to the Free Software 177fe2f639SDominik Brodowski * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 187fe2f639SDominik Brodowski */ 197fe2f639SDominik Brodowski 207fe2f639SDominik Brodowski #include <stdio.h> 217fe2f639SDominik Brodowski #include <stdlib.h> 227fe2f639SDominik Brodowski #include <stdarg.h> 237fe2f639SDominik Brodowski #include <string.h> 247fe2f639SDominik Brodowski #include <time.h> 257fe2f639SDominik Brodowski #include <dirent.h> 267fe2f639SDominik Brodowski 277fe2f639SDominik Brodowski #include <sys/utsname.h> 287fe2f639SDominik Brodowski #include <sys/types.h> 297fe2f639SDominik Brodowski #include <sys/stat.h> 307fe2f639SDominik Brodowski 317fe2f639SDominik Brodowski #include "parse.h" 327fe2f639SDominik Brodowski #include "config.h" 337fe2f639SDominik Brodowski 347fe2f639SDominik Brodowski /** 357fe2f639SDominik Brodowski * converts priority string to priority 367fe2f639SDominik Brodowski * 377fe2f639SDominik Brodowski * @param str string that represents a scheduler priority 387fe2f639SDominik Brodowski * 397fe2f639SDominik Brodowski * @retval priority 407fe2f639SDominik Brodowski * @retval SCHED_ERR when the priority doesn't exit 417fe2f639SDominik Brodowski **/ 427fe2f639SDominik Brodowski 437fe2f639SDominik Brodowski enum sched_prio string_to_prio(const char *str) 447fe2f639SDominik Brodowski { 457fe2f639SDominik Brodowski if (strncasecmp("high", str, strlen(str)) == 0) 467fe2f639SDominik Brodowski return SCHED_HIGH; 477fe2f639SDominik Brodowski else if (strncasecmp("default", str, strlen(str)) == 0) 487fe2f639SDominik Brodowski return SCHED_DEFAULT; 497fe2f639SDominik Brodowski else if (strncasecmp("low", str, strlen(str)) == 0) 507fe2f639SDominik Brodowski return SCHED_LOW; 517fe2f639SDominik Brodowski else 527fe2f639SDominik Brodowski return SCHED_ERR; 537fe2f639SDominik Brodowski } 547fe2f639SDominik Brodowski 557fe2f639SDominik Brodowski /** 567fe2f639SDominik Brodowski * create and open logfile 577fe2f639SDominik Brodowski * 587fe2f639SDominik Brodowski * @param dir directory in which the logfile should be created 597fe2f639SDominik Brodowski * 607fe2f639SDominik Brodowski * @retval logfile on success 617fe2f639SDominik Brodowski * @retval NULL when the file can't be created 627fe2f639SDominik Brodowski **/ 637fe2f639SDominik Brodowski 647fe2f639SDominik Brodowski FILE *prepare_output(const char *dirname) 657fe2f639SDominik Brodowski { 667fe2f639SDominik Brodowski FILE *output = NULL; 677fe2f639SDominik Brodowski int len; 687fe2f639SDominik Brodowski char *filename; 697fe2f639SDominik Brodowski struct utsname sysdata; 707fe2f639SDominik Brodowski DIR *dir; 717fe2f639SDominik Brodowski 727fe2f639SDominik Brodowski dir = opendir(dirname); 737fe2f639SDominik Brodowski if (dir == NULL) { 747fe2f639SDominik Brodowski if (mkdir(dirname, 0755)) { 757fe2f639SDominik Brodowski perror("mkdir"); 767fe2f639SDominik Brodowski fprintf(stderr, "error: Cannot create dir %s\n", 777fe2f639SDominik Brodowski dirname); 787fe2f639SDominik Brodowski return NULL; 797fe2f639SDominik Brodowski } 807fe2f639SDominik Brodowski } 817fe2f639SDominik Brodowski 827fe2f639SDominik Brodowski len = strlen(dirname) + 30; 837fe2f639SDominik Brodowski filename = malloc(sizeof(char) * len); 847fe2f639SDominik Brodowski 857fe2f639SDominik Brodowski if (uname(&sysdata) == 0) { 867fe2f639SDominik Brodowski len += strlen(sysdata.nodename) + strlen(sysdata.release); 877fe2f639SDominik Brodowski filename = realloc(filename, sizeof(char) * len); 887fe2f639SDominik Brodowski 897fe2f639SDominik Brodowski if (filename == NULL) { 907fe2f639SDominik Brodowski perror("realloc"); 917fe2f639SDominik Brodowski return NULL; 927fe2f639SDominik Brodowski } 937fe2f639SDominik Brodowski 947fe2f639SDominik Brodowski snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log", 957fe2f639SDominik Brodowski dirname, sysdata.nodename, sysdata.release, time(NULL)); 967fe2f639SDominik Brodowski } else { 97*02af3cb5SDominik Brodowski snprintf(filename, len - 1, "%s/benchmark_%li.log", 98*02af3cb5SDominik Brodowski dirname, time(NULL)); 997fe2f639SDominik Brodowski } 1007fe2f639SDominik Brodowski 1017fe2f639SDominik Brodowski dprintf("logilename: %s\n", filename); 1027fe2f639SDominik Brodowski 103*02af3cb5SDominik Brodowski output = fopen(filename, "w+"); 104*02af3cb5SDominik Brodowski if (output == NULL) { 1057fe2f639SDominik Brodowski perror("fopen"); 1067fe2f639SDominik Brodowski fprintf(stderr, "error: unable to open logfile\n"); 1077fe2f639SDominik Brodowski } 1087fe2f639SDominik Brodowski 1097fe2f639SDominik Brodowski fprintf(stdout, "Logfile: %s\n", filename); 1107fe2f639SDominik Brodowski 1117fe2f639SDominik Brodowski free(filename); 1127fe2f639SDominik Brodowski fprintf(output, "#round load sleep performance powersave percentage\n"); 1137fe2f639SDominik Brodowski return output; 1147fe2f639SDominik Brodowski } 1157fe2f639SDominik Brodowski 1167fe2f639SDominik Brodowski /** 1177fe2f639SDominik Brodowski * returns the default config 1187fe2f639SDominik Brodowski * 1197fe2f639SDominik Brodowski * @retval default config on success 1207fe2f639SDominik Brodowski * @retval NULL when the output file can't be created 1217fe2f639SDominik Brodowski **/ 1227fe2f639SDominik Brodowski 1237fe2f639SDominik Brodowski struct config *prepare_default_config() 1247fe2f639SDominik Brodowski { 1257fe2f639SDominik Brodowski struct config *config = malloc(sizeof(struct config)); 1267fe2f639SDominik Brodowski 1277fe2f639SDominik Brodowski dprintf("loading defaults\n"); 1287fe2f639SDominik Brodowski 1297fe2f639SDominik Brodowski config->sleep = 500000; 1307fe2f639SDominik Brodowski config->load = 500000; 1317fe2f639SDominik Brodowski config->sleep_step = 500000; 1327fe2f639SDominik Brodowski config->load_step = 500000; 1337fe2f639SDominik Brodowski config->cycles = 5; 1347fe2f639SDominik Brodowski config->rounds = 50; 1357fe2f639SDominik Brodowski config->cpu = 0; 1367fe2f639SDominik Brodowski config->prio = SCHED_HIGH; 1377fe2f639SDominik Brodowski config->verbose = 0; 1387fe2f639SDominik Brodowski strncpy(config->governor, "ondemand", 8); 1397fe2f639SDominik Brodowski 1407fe2f639SDominik Brodowski config->output = stdout; 1417fe2f639SDominik Brodowski 1427fe2f639SDominik Brodowski #ifdef DEFAULT_CONFIG_FILE 1437fe2f639SDominik Brodowski if (prepare_config(DEFAULT_CONFIG_FILE, config)) 1447fe2f639SDominik Brodowski return NULL; 1457fe2f639SDominik Brodowski #endif 1467fe2f639SDominik Brodowski return config; 1477fe2f639SDominik Brodowski } 1487fe2f639SDominik Brodowski 1497fe2f639SDominik Brodowski /** 1507fe2f639SDominik Brodowski * parses config file and returns the config to the caller 1517fe2f639SDominik Brodowski * 1527fe2f639SDominik Brodowski * @param path config file name 1537fe2f639SDominik Brodowski * 1547fe2f639SDominik Brodowski * @retval 1 on error 1557fe2f639SDominik Brodowski * @retval 0 on success 1567fe2f639SDominik Brodowski **/ 1577fe2f639SDominik Brodowski 1587fe2f639SDominik Brodowski int prepare_config(const char *path, struct config *config) 1597fe2f639SDominik Brodowski { 1607fe2f639SDominik Brodowski size_t len = 0; 1617fe2f639SDominik Brodowski char *opt, *val, *line = NULL; 1627fe2f639SDominik Brodowski FILE *configfile = fopen(path, "r"); 1637fe2f639SDominik Brodowski 1647fe2f639SDominik Brodowski if (config == NULL) { 1657fe2f639SDominik Brodowski fprintf(stderr, "error: config is NULL\n"); 1667fe2f639SDominik Brodowski return 1; 1677fe2f639SDominik Brodowski } 1687fe2f639SDominik Brodowski 1697fe2f639SDominik Brodowski if (configfile == NULL) { 1707fe2f639SDominik Brodowski perror("fopen"); 1717fe2f639SDominik Brodowski fprintf(stderr, "error: unable to read configfile\n"); 1727fe2f639SDominik Brodowski free(config); 1737fe2f639SDominik Brodowski return 1; 1747fe2f639SDominik Brodowski } 1757fe2f639SDominik Brodowski 176*02af3cb5SDominik Brodowski while (getline(&line, &len, configfile) != -1) { 1777fe2f639SDominik Brodowski if (line[0] == '#' || line[0] == ' ') 1787fe2f639SDominik Brodowski continue; 1797fe2f639SDominik Brodowski 1807fe2f639SDominik Brodowski sscanf(line, "%as = %as", &opt, &val); 1817fe2f639SDominik Brodowski 1827fe2f639SDominik Brodowski dprintf("parsing: %s -> %s\n", opt, val); 1837fe2f639SDominik Brodowski 1847fe2f639SDominik Brodowski if (strncmp("sleep", opt, strlen(opt)) == 0) 1857fe2f639SDominik Brodowski sscanf(val, "%li", &config->sleep); 1867fe2f639SDominik Brodowski 1877fe2f639SDominik Brodowski else if (strncmp("load", opt, strlen(opt)) == 0) 1887fe2f639SDominik Brodowski sscanf(val, "%li", &config->load); 1897fe2f639SDominik Brodowski 1907fe2f639SDominik Brodowski else if (strncmp("load_step", opt, strlen(opt)) == 0) 1917fe2f639SDominik Brodowski sscanf(val, "%li", &config->load_step); 1927fe2f639SDominik Brodowski 1937fe2f639SDominik Brodowski else if (strncmp("sleep_step", opt, strlen(opt)) == 0) 1947fe2f639SDominik Brodowski sscanf(val, "%li", &config->sleep_step); 1957fe2f639SDominik Brodowski 1967fe2f639SDominik Brodowski else if (strncmp("cycles", opt, strlen(opt)) == 0) 1977fe2f639SDominik Brodowski sscanf(val, "%u", &config->cycles); 1987fe2f639SDominik Brodowski 1997fe2f639SDominik Brodowski else if (strncmp("rounds", opt, strlen(opt)) == 0) 2007fe2f639SDominik Brodowski sscanf(val, "%u", &config->rounds); 2017fe2f639SDominik Brodowski 2027fe2f639SDominik Brodowski else if (strncmp("verbose", opt, strlen(opt)) == 0) 2037fe2f639SDominik Brodowski sscanf(val, "%u", &config->verbose); 2047fe2f639SDominik Brodowski 2057fe2f639SDominik Brodowski else if (strncmp("output", opt, strlen(opt)) == 0) 2067fe2f639SDominik Brodowski config->output = prepare_output(val); 2077fe2f639SDominik Brodowski 2087fe2f639SDominik Brodowski else if (strncmp("cpu", opt, strlen(opt)) == 0) 2097fe2f639SDominik Brodowski sscanf(val, "%u", &config->cpu); 2107fe2f639SDominik Brodowski 2117fe2f639SDominik Brodowski else if (strncmp("governor", opt, 14) == 0) 2127fe2f639SDominik Brodowski strncpy(config->governor, val, 14); 2137fe2f639SDominik Brodowski 2147fe2f639SDominik Brodowski else if (strncmp("priority", opt, strlen(opt)) == 0) { 2157fe2f639SDominik Brodowski if (string_to_prio(val) != SCHED_ERR) 2167fe2f639SDominik Brodowski config->prio = string_to_prio(val); 2177fe2f639SDominik Brodowski } 2187fe2f639SDominik Brodowski } 2197fe2f639SDominik Brodowski 2207fe2f639SDominik Brodowski free(line); 2217fe2f639SDominik Brodowski free(opt); 2227fe2f639SDominik Brodowski free(val); 2237fe2f639SDominik Brodowski 2247fe2f639SDominik Brodowski return 0; 2257fe2f639SDominik Brodowski } 226