xref: /linux/tools/power/cpupower/bench/system.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*1a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27fe2f639SDominik Brodowski /*  cpufreq-bench CPUFreq microbenchmark
37fe2f639SDominik Brodowski  *
47fe2f639SDominik Brodowski  *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
57fe2f639SDominik Brodowski  */
67fe2f639SDominik Brodowski 
77fe2f639SDominik Brodowski #include <stdio.h>
87fe2f639SDominik Brodowski #include <time.h>
97fe2f639SDominik Brodowski #include <sys/time.h>
107fe2f639SDominik Brodowski #include <sys/types.h>
117fe2f639SDominik Brodowski #include <unistd.h>
127fe2f639SDominik Brodowski 
137fe2f639SDominik Brodowski #include <sched.h>
147fe2f639SDominik Brodowski 
157fe2f639SDominik Brodowski #include <cpufreq.h>
16ac5a181dSThomas Renninger #include <cpupower.h>
177fe2f639SDominik Brodowski 
187fe2f639SDominik Brodowski #include "config.h"
197fe2f639SDominik Brodowski #include "system.h"
207fe2f639SDominik Brodowski 
217fe2f639SDominik Brodowski /**
2202af3cb5SDominik Brodowski  * returns time since epoch in µs
237fe2f639SDominik Brodowski  *
247fe2f639SDominik Brodowski  * @retval time
257fe2f639SDominik Brodowski  **/
267fe2f639SDominik Brodowski 
get_time()277fe2f639SDominik Brodowski long long int get_time()
287fe2f639SDominik Brodowski {
297fe2f639SDominik Brodowski 	struct timeval now;
307fe2f639SDominik Brodowski 
317fe2f639SDominik Brodowski 	gettimeofday(&now, NULL);
327fe2f639SDominik Brodowski 
337fe2f639SDominik Brodowski 	return (long long int)(now.tv_sec * 1000000LL + now.tv_usec);
347fe2f639SDominik Brodowski }
357fe2f639SDominik Brodowski 
367fe2f639SDominik Brodowski /**
377fe2f639SDominik Brodowski  * sets the cpufreq governor
387fe2f639SDominik Brodowski  *
397fe2f639SDominik Brodowski  * @param governor cpufreq governor name
407fe2f639SDominik Brodowski  * @param cpu cpu for which the governor should be set
417fe2f639SDominik Brodowski  *
427fe2f639SDominik Brodowski  * @retval 0 on success
437fe2f639SDominik Brodowski  * @retval -1 when failed
447fe2f639SDominik Brodowski  **/
457fe2f639SDominik Brodowski 
set_cpufreq_governor(char * governor,unsigned int cpu)467fe2f639SDominik Brodowski int set_cpufreq_governor(char *governor, unsigned int cpu)
477fe2f639SDominik Brodowski {
487fe2f639SDominik Brodowski 
497fe2f639SDominik Brodowski 	dprintf("set %s as cpufreq governor\n", governor);
507fe2f639SDominik Brodowski 
5153d1cd6bSAbhishek Goel 	if (cpupower_is_cpu_online(cpu) != 1) {
527fe2f639SDominik Brodowski 		perror("cpufreq_cpu_exists");
537fe2f639SDominik Brodowski 		fprintf(stderr, "error: cpu %u does not exist\n", cpu);
547fe2f639SDominik Brodowski 		return -1;
557fe2f639SDominik Brodowski 	}
567fe2f639SDominik Brodowski 
577fe2f639SDominik Brodowski 	if (cpufreq_modify_policy_governor(cpu, governor) != 0) {
587fe2f639SDominik Brodowski 		perror("cpufreq_modify_policy_governor");
597fe2f639SDominik Brodowski 		fprintf(stderr, "error: unable to set %s governor\n", governor);
607fe2f639SDominik Brodowski 		return -1;
617fe2f639SDominik Brodowski 	}
627fe2f639SDominik Brodowski 
637fe2f639SDominik Brodowski 	return 0;
647fe2f639SDominik Brodowski }
657fe2f639SDominik Brodowski 
667fe2f639SDominik Brodowski /**
677fe2f639SDominik Brodowski  * sets cpu affinity for the process
687fe2f639SDominik Brodowski  *
697fe2f639SDominik Brodowski  * @param cpu cpu# to which the affinity should be set
707fe2f639SDominik Brodowski  *
717fe2f639SDominik Brodowski  * @retval 0 on success
727fe2f639SDominik Brodowski  * @retval -1 when setting the affinity failed
737fe2f639SDominik Brodowski  **/
747fe2f639SDominik Brodowski 
set_cpu_affinity(unsigned int cpu)757fe2f639SDominik Brodowski int set_cpu_affinity(unsigned int cpu)
767fe2f639SDominik Brodowski {
777fe2f639SDominik Brodowski 	cpu_set_t cpuset;
787fe2f639SDominik Brodowski 
797fe2f639SDominik Brodowski 	CPU_ZERO(&cpuset);
807fe2f639SDominik Brodowski 	CPU_SET(cpu, &cpuset);
817fe2f639SDominik Brodowski 
827fe2f639SDominik Brodowski 	dprintf("set affinity to cpu #%u\n", cpu);
837fe2f639SDominik Brodowski 
847fe2f639SDominik Brodowski 	if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) {
857fe2f639SDominik Brodowski 		perror("sched_setaffinity");
867fe2f639SDominik Brodowski 		fprintf(stderr, "warning: unable to set cpu affinity\n");
877fe2f639SDominik Brodowski 		return -1;
887fe2f639SDominik Brodowski 	}
897fe2f639SDominik Brodowski 
907fe2f639SDominik Brodowski 	return 0;
917fe2f639SDominik Brodowski }
927fe2f639SDominik Brodowski 
937fe2f639SDominik Brodowski /**
947fe2f639SDominik Brodowski  * sets the process priority parameter
957fe2f639SDominik Brodowski  *
967fe2f639SDominik Brodowski  * @param priority priority value
977fe2f639SDominik Brodowski  *
987fe2f639SDominik Brodowski  * @retval 0 on success
997fe2f639SDominik Brodowski  * @retval -1 when setting the priority failed
1007fe2f639SDominik Brodowski  **/
1017fe2f639SDominik Brodowski 
set_process_priority(int priority)1027fe2f639SDominik Brodowski int set_process_priority(int priority)
1037fe2f639SDominik Brodowski {
1047fe2f639SDominik Brodowski 	struct sched_param param;
1057fe2f639SDominik Brodowski 
1067fe2f639SDominik Brodowski 	dprintf("set scheduler priority to %i\n", priority);
1077fe2f639SDominik Brodowski 
1087fe2f639SDominik Brodowski 	param.sched_priority = priority;
1097fe2f639SDominik Brodowski 
1107fe2f639SDominik Brodowski 	if (sched_setscheduler(0, SCHEDULER, &param) < 0) {
1117fe2f639SDominik Brodowski 		perror("sched_setscheduler");
1127fe2f639SDominik Brodowski 		fprintf(stderr, "warning: unable to set scheduler priority\n");
1137fe2f639SDominik Brodowski 		return -1;
1147fe2f639SDominik Brodowski 	}
1157fe2f639SDominik Brodowski 
1167fe2f639SDominik Brodowski 	return 0;
1177fe2f639SDominik Brodowski }
1187fe2f639SDominik Brodowski 
1197fe2f639SDominik Brodowski /**
12002af3cb5SDominik Brodowski  * notifies the user that the benchmark may run some time
1217fe2f639SDominik Brodowski  *
1227fe2f639SDominik Brodowski  * @param config benchmark config values
1237fe2f639SDominik Brodowski  *
1247fe2f639SDominik Brodowski  **/
1257fe2f639SDominik Brodowski 
prepare_user(const struct config * config)1267fe2f639SDominik Brodowski void prepare_user(const struct config *config)
1277fe2f639SDominik Brodowski {
1287fe2f639SDominik Brodowski 	unsigned long sleep_time = 0;
1297fe2f639SDominik Brodowski 	unsigned long load_time = 0;
1307fe2f639SDominik Brodowski 	unsigned int round;
1317fe2f639SDominik Brodowski 
1327fe2f639SDominik Brodowski 	for (round = 0; round < config->rounds; round++) {
13302af3cb5SDominik Brodowski 		sleep_time +=  2 * config->cycles *
13402af3cb5SDominik Brodowski 			(config->sleep + config->sleep_step * round);
13502af3cb5SDominik Brodowski 		load_time += 2 * config->cycles *
13602af3cb5SDominik Brodowski 			(config->load + config->load_step * round) +
13702af3cb5SDominik Brodowski 			(config->load + config->load_step * round * 4);
1387fe2f639SDominik Brodowski 	}
1397fe2f639SDominik Brodowski 
1407fe2f639SDominik Brodowski 	if (config->verbose || config->output != stdout)
1417fe2f639SDominik Brodowski 		printf("approx. test duration: %im\n",
1427fe2f639SDominik Brodowski 		       (int)((sleep_time + load_time) / 60000000));
1437fe2f639SDominik Brodowski }
1447fe2f639SDominik Brodowski 
1457fe2f639SDominik Brodowski /**
1467fe2f639SDominik Brodowski  * sets up the cpu affinity and scheduler priority
1477fe2f639SDominik Brodowski  *
1487fe2f639SDominik Brodowski  * @param config benchmark config values
1497fe2f639SDominik Brodowski  *
1507fe2f639SDominik Brodowski  **/
1517fe2f639SDominik Brodowski 
prepare_system(const struct config * config)1527fe2f639SDominik Brodowski void prepare_system(const struct config *config)
1537fe2f639SDominik Brodowski {
1547fe2f639SDominik Brodowski 	if (config->verbose)
1557fe2f639SDominik Brodowski 		printf("set cpu affinity to cpu #%u\n", config->cpu);
1567fe2f639SDominik Brodowski 
1577fe2f639SDominik Brodowski 	set_cpu_affinity(config->cpu);
1587fe2f639SDominik Brodowski 
1597fe2f639SDominik Brodowski 	switch (config->prio) {
1607fe2f639SDominik Brodowski 	case SCHED_HIGH:
1617fe2f639SDominik Brodowski 		if (config->verbose)
1627fe2f639SDominik Brodowski 			printf("high priority condition requested\n");
1637fe2f639SDominik Brodowski 
1647fe2f639SDominik Brodowski 		set_process_priority(PRIORITY_HIGH);
1657fe2f639SDominik Brodowski 		break;
1667fe2f639SDominik Brodowski 	case SCHED_LOW:
1677fe2f639SDominik Brodowski 		if (config->verbose)
1687fe2f639SDominik Brodowski 			printf("low priority condition requested\n");
1697fe2f639SDominik Brodowski 
1707fe2f639SDominik Brodowski 		set_process_priority(PRIORITY_LOW);
1717fe2f639SDominik Brodowski 		break;
1727fe2f639SDominik Brodowski 	default:
1737fe2f639SDominik Brodowski 		if (config->verbose)
1747fe2f639SDominik Brodowski 			printf("default priority condition requested\n");
1757fe2f639SDominik Brodowski 
1767fe2f639SDominik Brodowski 		set_process_priority(PRIORITY_DEFAULT);
1777fe2f639SDominik Brodowski 	}
1787fe2f639SDominik Brodowski }
1797fe2f639SDominik Brodowski 
180