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