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