1/* cpufreq-bench CPUFreq microbenchmark 2 * 3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 */ 19 20#include <stdio.h> 21#include <time.h> 22#include <sys/time.h> 23#include <sys/types.h> 24#include <unistd.h> 25 26#include <sched.h> 27 28#include <cpufreq.h> 29 30#include "config.h" 31#include "system.h" 32 33/** 34 * returns time since epoch in µs 35 * 36 * @retval time 37 **/ 38 39long long int get_time() 40{ 41 struct timeval now; 42 43 gettimeofday(&now, NULL); 44 45 return (long long int)(now.tv_sec * 1000000LL + now.tv_usec); 46} 47 48/** 49 * sets the cpufreq governor 50 * 51 * @param governor cpufreq governor name 52 * @param cpu cpu for which the governor should be set 53 * 54 * @retval 0 on success 55 * @retval -1 when failed 56 **/ 57 58int set_cpufreq_governor(char *governor, unsigned int cpu) 59{ 60 61 dprintf("set %s as cpufreq governor\n", governor); 62 63 if (cpufreq_cpu_exists(cpu) != 0) { 64 perror("cpufreq_cpu_exists"); 65 fprintf(stderr, "error: cpu %u does not exist\n", cpu); 66 return -1; 67 } 68 69 if (cpufreq_modify_policy_governor(cpu, governor) != 0) { 70 perror("cpufreq_modify_policy_governor"); 71 fprintf(stderr, "error: unable to set %s governor\n", governor); 72 return -1; 73 } 74 75 return 0; 76} 77 78/** 79 * sets cpu affinity for the process 80 * 81 * @param cpu cpu# to which the affinity should be set 82 * 83 * @retval 0 on success 84 * @retval -1 when setting the affinity failed 85 **/ 86 87int set_cpu_affinity(unsigned int cpu) 88{ 89 cpu_set_t cpuset; 90 91 CPU_ZERO(&cpuset); 92 CPU_SET(cpu, &cpuset); 93 94 dprintf("set affinity to cpu #%u\n", cpu); 95 96 if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) { 97 perror("sched_setaffinity"); 98 fprintf(stderr, "warning: unable to set cpu affinity\n"); 99 return -1; 100 } 101 102 return 0; 103} 104 105/** 106 * sets the process priority parameter 107 * 108 * @param priority priority value 109 * 110 * @retval 0 on success 111 * @retval -1 when setting the priority failed 112 **/ 113 114int set_process_priority(int priority) 115{ 116 struct sched_param param; 117 118 dprintf("set scheduler priority to %i\n", priority); 119 120 param.sched_priority = priority; 121 122 if (sched_setscheduler(0, SCHEDULER, ¶m) < 0) { 123 perror("sched_setscheduler"); 124 fprintf(stderr, "warning: unable to set scheduler priority\n"); 125 return -1; 126 } 127 128 return 0; 129} 130 131/** 132 * notifies the user that the benchmark may run some time 133 * 134 * @param config benchmark config values 135 * 136 **/ 137 138void prepare_user(const struct config *config) 139{ 140 unsigned long sleep_time = 0; 141 unsigned long load_time = 0; 142 unsigned int round; 143 144 for (round = 0; round < config->rounds; round++) { 145 sleep_time += 2 * config->cycles * 146 (config->sleep + config->sleep_step * round); 147 load_time += 2 * config->cycles * 148 (config->load + config->load_step * round) + 149 (config->load + config->load_step * round * 4); 150 } 151 152 if (config->verbose || config->output != stdout) 153 printf("approx. test duration: %im\n", 154 (int)((sleep_time + load_time) / 60000000)); 155} 156 157/** 158 * sets up the cpu affinity and scheduler priority 159 * 160 * @param config benchmark config values 161 * 162 **/ 163 164void prepare_system(const struct config *config) 165{ 166 if (config->verbose) 167 printf("set cpu affinity to cpu #%u\n", config->cpu); 168 169 set_cpu_affinity(config->cpu); 170 171 switch (config->prio) { 172 case SCHED_HIGH: 173 if (config->verbose) 174 printf("high priority condition requested\n"); 175 176 set_process_priority(PRIORITY_HIGH); 177 break; 178 case SCHED_LOW: 179 if (config->verbose) 180 printf("low priority condition requested\n"); 181 182 set_process_priority(PRIORITY_LOW); 183 break; 184 default: 185 if (config->verbose) 186 printf("default priority condition requested\n"); 187 188 set_process_priority(PRIORITY_DEFAULT); 189 } 190} 191 192