linux/tools/power/cpupower/bench/system.c
<<
>>
Prefs
   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
  40long 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
  59int 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
  88int 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
 115int 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, &param) < 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
 139void 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
 165void 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