162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*  cpufreq-bench CPUFreq microbenchmark
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <stdio.h>
862306a36Sopenharmony_ci#include <stdlib.h>
962306a36Sopenharmony_ci#include <string.h>
1062306a36Sopenharmony_ci#include <unistd.h>
1162306a36Sopenharmony_ci#include <getopt.h>
1262306a36Sopenharmony_ci#include <errno.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "config.h"
1562306a36Sopenharmony_ci#include "system.h"
1662306a36Sopenharmony_ci#include "benchmark.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic struct option long_options[] = {
1962306a36Sopenharmony_ci	{"output",	1,	0,	'o'},
2062306a36Sopenharmony_ci	{"sleep",	1,	0,	's'},
2162306a36Sopenharmony_ci	{"load",	1,	0,	'l'},
2262306a36Sopenharmony_ci	{"verbose",	0,	0,	'v'},
2362306a36Sopenharmony_ci	{"cpu",		1,	0,	'c'},
2462306a36Sopenharmony_ci	{"governor",	1,	0,	'g'},
2562306a36Sopenharmony_ci	{"prio",	1,	0,	'p'},
2662306a36Sopenharmony_ci	{"file",	1,	0,	'f'},
2762306a36Sopenharmony_ci	{"cycles",	1,	0,	'n'},
2862306a36Sopenharmony_ci	{"rounds",	1,	0,	'r'},
2962306a36Sopenharmony_ci	{"load-step",	1,	0,	'x'},
3062306a36Sopenharmony_ci	{"sleep-step",	1,	0,	'y'},
3162306a36Sopenharmony_ci	{"help",	0,	0,	'h'},
3262306a36Sopenharmony_ci	{0, 0, 0, 0}
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/*******************************************************************
3662306a36Sopenharmony_ci usage
3762306a36Sopenharmony_ci*******************************************************************/
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_civoid usage()
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	printf("usage: ./bench\n");
4262306a36Sopenharmony_ci	printf("Options:\n");
4362306a36Sopenharmony_ci	printf(" -l, --load=<long int>\t\tinitial load time in us\n");
4462306a36Sopenharmony_ci	printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n");
4562306a36Sopenharmony_ci	printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n");
4662306a36Sopenharmony_ci	printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n");
4762306a36Sopenharmony_ci	printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n");
4862306a36Sopenharmony_ci	printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n");
4962306a36Sopenharmony_ci	printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n");
5062306a36Sopenharmony_ci	printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n");
5162306a36Sopenharmony_ci	printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n");
5262306a36Sopenharmony_ci	printf(" -f, --file=<configfile>\t\tconfig file to use\n");
5362306a36Sopenharmony_ci	printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n");
5462306a36Sopenharmony_ci	printf(" -v, --verbose\t\t\t\tverbose output on/off\n");
5562306a36Sopenharmony_ci	printf(" -h, --help\t\t\t\tPrint this help screen\n");
5662306a36Sopenharmony_ci	exit(1);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/*******************************************************************
6062306a36Sopenharmony_ci main
6162306a36Sopenharmony_ci*******************************************************************/
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciint main(int argc, char **argv)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	int c;
6662306a36Sopenharmony_ci	int option_index = 0;
6762306a36Sopenharmony_ci	struct config *config = NULL;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	config = prepare_default_config();
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	if (config == NULL)
7262306a36Sopenharmony_ci		return EXIT_FAILURE;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	while (1) {
7562306a36Sopenharmony_ci		c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:",
7662306a36Sopenharmony_ci				long_options, &option_index);
7762306a36Sopenharmony_ci		if (c == -1)
7862306a36Sopenharmony_ci			break;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci		switch (c) {
8162306a36Sopenharmony_ci		case 'o':
8262306a36Sopenharmony_ci			if (config->output != NULL)
8362306a36Sopenharmony_ci				fclose(config->output);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci			config->output = prepare_output(optarg);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci			if (config->output == NULL)
8862306a36Sopenharmony_ci				return EXIT_FAILURE;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci			dprintf("user output path -> %s\n", optarg);
9162306a36Sopenharmony_ci			break;
9262306a36Sopenharmony_ci		case 's':
9362306a36Sopenharmony_ci			sscanf(optarg, "%li", &config->sleep);
9462306a36Sopenharmony_ci			dprintf("user sleep time -> %s\n", optarg);
9562306a36Sopenharmony_ci			break;
9662306a36Sopenharmony_ci		case 'l':
9762306a36Sopenharmony_ci			sscanf(optarg, "%li", &config->load);
9862306a36Sopenharmony_ci			dprintf("user load time -> %s\n", optarg);
9962306a36Sopenharmony_ci			break;
10062306a36Sopenharmony_ci		case 'c':
10162306a36Sopenharmony_ci			sscanf(optarg, "%u", &config->cpu);
10262306a36Sopenharmony_ci			dprintf("user cpu -> %s\n", optarg);
10362306a36Sopenharmony_ci			break;
10462306a36Sopenharmony_ci		case 'g':
10562306a36Sopenharmony_ci			strncpy(config->governor, optarg, 14);
10662306a36Sopenharmony_ci			dprintf("user governor -> %s\n", optarg);
10762306a36Sopenharmony_ci			break;
10862306a36Sopenharmony_ci		case 'p':
10962306a36Sopenharmony_ci			if (string_to_prio(optarg) != SCHED_ERR) {
11062306a36Sopenharmony_ci				config->prio = string_to_prio(optarg);
11162306a36Sopenharmony_ci				dprintf("user prio -> %s\n", optarg);
11262306a36Sopenharmony_ci			} else {
11362306a36Sopenharmony_ci				if (config != NULL) {
11462306a36Sopenharmony_ci					if (config->output != NULL)
11562306a36Sopenharmony_ci						fclose(config->output);
11662306a36Sopenharmony_ci					free(config);
11762306a36Sopenharmony_ci				}
11862306a36Sopenharmony_ci				usage();
11962306a36Sopenharmony_ci			}
12062306a36Sopenharmony_ci			break;
12162306a36Sopenharmony_ci		case 'n':
12262306a36Sopenharmony_ci			sscanf(optarg, "%u", &config->cycles);
12362306a36Sopenharmony_ci			dprintf("user cycles -> %s\n", optarg);
12462306a36Sopenharmony_ci			break;
12562306a36Sopenharmony_ci		case 'r':
12662306a36Sopenharmony_ci			sscanf(optarg, "%u", &config->rounds);
12762306a36Sopenharmony_ci			dprintf("user rounds -> %s\n", optarg);
12862306a36Sopenharmony_ci			break;
12962306a36Sopenharmony_ci		case 'x':
13062306a36Sopenharmony_ci			sscanf(optarg, "%li", &config->load_step);
13162306a36Sopenharmony_ci			dprintf("user load_step -> %s\n", optarg);
13262306a36Sopenharmony_ci			break;
13362306a36Sopenharmony_ci		case 'y':
13462306a36Sopenharmony_ci			sscanf(optarg, "%li", &config->sleep_step);
13562306a36Sopenharmony_ci			dprintf("user sleep_step -> %s\n", optarg);
13662306a36Sopenharmony_ci			break;
13762306a36Sopenharmony_ci		case 'f':
13862306a36Sopenharmony_ci			if (prepare_config(optarg, config))
13962306a36Sopenharmony_ci				return EXIT_FAILURE;
14062306a36Sopenharmony_ci			break;
14162306a36Sopenharmony_ci		case 'v':
14262306a36Sopenharmony_ci			config->verbose = 1;
14362306a36Sopenharmony_ci			dprintf("verbose output enabled\n");
14462306a36Sopenharmony_ci			break;
14562306a36Sopenharmony_ci		case 'h':
14662306a36Sopenharmony_ci		case '?':
14762306a36Sopenharmony_ci		default:
14862306a36Sopenharmony_ci			if (config != NULL) {
14962306a36Sopenharmony_ci				if (config->output != NULL)
15062306a36Sopenharmony_ci					fclose(config->output);
15162306a36Sopenharmony_ci				free(config);
15262306a36Sopenharmony_ci			}
15362306a36Sopenharmony_ci			usage();
15462306a36Sopenharmony_ci		}
15562306a36Sopenharmony_ci	}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	if (config->verbose) {
15862306a36Sopenharmony_ci		printf("starting benchmark with parameters:\n");
15962306a36Sopenharmony_ci		printf("config:\n\t"
16062306a36Sopenharmony_ci		       "sleep=%li\n\t"
16162306a36Sopenharmony_ci		       "load=%li\n\t"
16262306a36Sopenharmony_ci		       "sleep_step=%li\n\t"
16362306a36Sopenharmony_ci		       "load_step=%li\n\t"
16462306a36Sopenharmony_ci		       "cpu=%u\n\t"
16562306a36Sopenharmony_ci		       "cycles=%u\n\t"
16662306a36Sopenharmony_ci		       "rounds=%u\n\t"
16762306a36Sopenharmony_ci		       "governor=%s\n\n",
16862306a36Sopenharmony_ci		       config->sleep,
16962306a36Sopenharmony_ci		       config->load,
17062306a36Sopenharmony_ci		       config->sleep_step,
17162306a36Sopenharmony_ci		       config->load_step,
17262306a36Sopenharmony_ci		       config->cpu,
17362306a36Sopenharmony_ci		       config->cycles,
17462306a36Sopenharmony_ci		       config->rounds,
17562306a36Sopenharmony_ci		       config->governor);
17662306a36Sopenharmony_ci	}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	prepare_user(config);
17962306a36Sopenharmony_ci	prepare_system(config);
18062306a36Sopenharmony_ci	start_benchmark(config);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	if (config->output != stdout)
18362306a36Sopenharmony_ci		fclose(config->output);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	free(config);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	return EXIT_SUCCESS;
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
190