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