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 #include <cpupower.h> 30 31 #include "config.h" 32 #include "system.h" 33 34 /** 35 * returns time since epoch in µs 36 * 37 * @retval time 38 **/ 39 40 long long int get_time() 41 { 42 struct timeval now; 43 44 gettimeofday(&now, NULL); 45 46 return (long long int)(now.tv_sec * 1000000LL + now.tv_usec); 47 } 48 49 /** 50 * sets the cpufreq governor 51 * 52 * @param governor cpufreq governor name 53 * @param cpu cpu for which the governor should be set 54 * 55 * @retval 0 on success 56 * @retval -1 when failed 57 **/ 58 59 int set_cpufreq_governor(char *governor, unsigned int cpu) 60 { 61 62 dprintf("set %s as cpufreq governor\n", governor); 63 64 if (cpupower_is_cpu_online(cpu) != 0) { 65 perror("cpufreq_cpu_exists"); 66 fprintf(stderr, "error: cpu %u does not exist\n", cpu); 67 return -1; 68 } 69 70 if (cpufreq_modify_policy_governor(cpu, governor) != 0) { 71 perror("cpufreq_modify_policy_governor"); 72 fprintf(stderr, "error: unable to set %s governor\n", governor); 73 return -1; 74 } 75 76 return 0; 77 } 78 79 /** 80 * sets cpu affinity for the process 81 * 82 * @param cpu cpu# to which the affinity should be set 83 * 84 * @retval 0 on success 85 * @retval -1 when setting the affinity failed 86 **/ 87 88 int set_cpu_affinity(unsigned int cpu) 89 { 90 cpu_set_t cpuset; 91 92 CPU_ZERO(&cpuset); 93 CPU_SET(cpu, &cpuset); 94 95 dprintf("set affinity to cpu #%u\n", cpu); 96 97 if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) { 98 perror("sched_setaffinity"); 99 fprintf(stderr, "warning: unable to set cpu affinity\n"); 100 return -1; 101 } 102 103 return 0; 104 } 105 106 /** 107 * sets the process priority parameter 108 * 109 * @param priority priority value 110 * 111 * @retval 0 on success 112 * @retval -1 when setting the priority failed 113 **/ 114 115 int set_process_priority(int priority) 116 { 117 struct sched_param param; 118 119 dprintf("set scheduler priority to %i\n", priority); 120 121 param.sched_priority = priority; 122 123 if (sched_setscheduler(0, SCHEDULER, ¶m) < 0) { 124 perror("sched_setscheduler"); 125 fprintf(stderr, "warning: unable to set scheduler priority\n"); 126 return -1; 127 } 128 129 return 0; 130 } 131 132 /** 133 * notifies the user that the benchmark may run some time 134 * 135 * @param config benchmark config values 136 * 137 **/ 138 139 void prepare_user(const struct config *config) 140 { 141 unsigned long sleep_time = 0; 142 unsigned long load_time = 0; 143 unsigned int round; 144 145 for (round = 0; round < config->rounds; round++) { 146 sleep_time += 2 * config->cycles * 147 (config->sleep + config->sleep_step * round); 148 load_time += 2 * config->cycles * 149 (config->load + config->load_step * round) + 150 (config->load + config->load_step * round * 4); 151 } 152 153 if (config->verbose || config->output != stdout) 154 printf("approx. test duration: %im\n", 155 (int)((sleep_time + load_time) / 60000000)); 156 } 157 158 /** 159 * sets up the cpu affinity and scheduler priority 160 * 161 * @param config benchmark config values 162 * 163 **/ 164 165 void prepare_system(const struct config *config) 166 { 167 if (config->verbose) 168 printf("set cpu affinity to cpu #%u\n", config->cpu); 169 170 set_cpu_affinity(config->cpu); 171 172 switch (config->prio) { 173 case SCHED_HIGH: 174 if (config->verbose) 175 printf("high priority condition requested\n"); 176 177 set_process_priority(PRIORITY_HIGH); 178 break; 179 case SCHED_LOW: 180 if (config->verbose) 181 printf("low priority condition requested\n"); 182 183 set_process_priority(PRIORITY_LOW); 184 break; 185 default: 186 if (config->verbose) 187 printf("default priority condition requested\n"); 188 189 set_process_priority(PRIORITY_DEFAULT); 190 } 191 } 192 193