^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* cpufreq-bench CPUFreq microbenchmark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <getopt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "system.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "benchmark.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static struct option long_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {"output", 1, 0, 'o'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {"sleep", 1, 0, 's'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {"load", 1, 0, 'l'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {"verbose", 0, 0, 'v'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {"cpu", 1, 0, 'c'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {"governor", 1, 0, 'g'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {"prio", 1, 0, 'p'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {"file", 1, 0, 'f'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {"cycles", 1, 0, 'n'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {"rounds", 1, 0, 'r'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {"load-step", 1, 0, 'x'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {"sleep-step", 1, 0, 'y'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {"help", 0, 0, 'h'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {0, 0, 0, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*******************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) usage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) void usage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) printf("usage: ./bench\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) printf("Options:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) printf(" -l, --load=<long int>\t\tinitial load time in us\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) printf(" -f, --file=<configfile>\t\tconfig file to use\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) printf(" -v, --verbose\t\t\t\tverbose output on/off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) printf(" -h, --help\t\t\t\tPrint this help screen\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*******************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) main
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int option_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct config *config = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) config = prepare_default_config();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (config == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) long_options, &option_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (c == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (config->output != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) fclose(config->output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) config->output = prepare_output(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (config->output == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dprintf("user output path -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sscanf(optarg, "%li", &config->sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dprintf("user sleep time -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) sscanf(optarg, "%li", &config->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dprintf("user load time -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) sscanf(optarg, "%u", &config->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dprintf("user cpu -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 'g':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) strncpy(config->governor, optarg, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dprintf("user governor -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (string_to_prio(optarg) != SCHED_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) config->prio = string_to_prio(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dprintf("user prio -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (config != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (config->output != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) fclose(config->output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) free(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sscanf(optarg, "%u", &config->cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dprintf("user cycles -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) sscanf(optarg, "%u", &config->rounds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dprintf("user rounds -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) sscanf(optarg, "%li", &config->load_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dprintf("user load_step -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case 'y':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sscanf(optarg, "%li", &config->sleep_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dprintf("user sleep_step -> %s\n", optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (prepare_config(optarg, config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case 'v':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) config->verbose = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dprintf("verbose output enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (config != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (config->output != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fclose(config->output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) free(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (config->verbose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) printf("starting benchmark with parameters:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) printf("config:\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) "sleep=%li\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "load=%li\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "sleep_step=%li\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "load_step=%li\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) "cpu=%u\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) "cycles=%u\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) "rounds=%u\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "governor=%s\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) config->sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) config->load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) config->sleep_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) config->load_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) config->cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) config->cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) config->rounds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) config->governor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) prepare_user(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) prepare_system(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) start_benchmark(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (config->output != stdout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) fclose(config->output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) free(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return EXIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)