[543be6]: libutil / op_cpufreq.c Maximize Restore History

Download this file

op_cpufreq.c    137 lines (112 with data), 2.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* @file op_cpufreq.c
* get cpu frequency definition
*
* @remark Copyright 2011 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon
* @author Philippe Elie
* @author Suravee Suthikulpanit
*/
#include <stdio.h>
#include <stdlib.h>
#include "op_fileio.h"
/*
* Use frequency information from /proc/cpuinfo. This should be available in most case.
* However, this number is the current cpu frequency which could be in the idle state.
* We should actually report the max frequency because the cpu should switch into the
* highest power state when running.
*/
static double op_cpu_freq_cpuinfo(void)
{
double fval = 0.0;
unsigned long uval;
char * line = NULL;
FILE * fp = op_try_open_file("/proc/cpuinfo", "r");
if (!fp)
return 0.0;
while (1) {
line = op_get_line(fp);
if (!line)
break;
if (line[0] == '\0') {
free(line);
continue;
}
/* x86/parisc/ia64/x86_64 */
if (sscanf(line, "cpu MHz : %lf", &fval) == 1)
break;
/* ppc/ppc64 */
if (sscanf(line, "clock : %lfMHz", &fval) == 1)
break;
/* alpha */
if (sscanf(line, "cycle frequency [Hz] : %lu", &uval) == 1) {
fval = uval / 1E6;
break;
}
/* sparc64 if CONFIG_SMP only */
if (sscanf(line, "Cpu0ClkTck : %lx", &uval) == 1) {
fval = uval / 1E6;
break;
}
/* mips including loongson2 */
if (sscanf(line, "BogoMIPS : %lu", &uval) == 1) {
fval = uval * 3 / 2;
break;
}
/* s390 doesn't provide cpu freq, checked up to 2.6-test4 */
free(line);
}
if (line)
free(line);
op_close_file(fp);
return fval;
}
/*
* Use frequency information from /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
* This number is the maximum cpu frequency of the processor.
*/
static double op_cpu_freq_sys_devices(void)
{
double fval = 0.0;
char * line = NULL;
FILE * fp = op_try_open_file("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
if (!fp)
return 0.0;
while (1) {
line = op_get_line(fp);
if (!line)
break;
if (line[0] == '\0') {
free(line);
continue;
}
if (sscanf(line, "%lf", &fval) == 1)
break;
free(line);
}
if (line)
free(line);
op_close_file(fp);
/* Return the frequency in MHz. When the frequency is
* printed it is assumed to be in units of MHz.
*/
return fval/1000;
}
double op_cpu_frequency(void)
{
/*
* Typically, system changes the frequency scaling of the cpus
* based on the workload. /proc/cpuinfo reports the current
* frequency value which might not be at the maximum at the time
* of query. Since cpu switch into running state with max frequency
* when under workload, we should make sure to report the max frequency
* value acquiring from /sys/devices when available.
*/
double freq = op_cpu_freq_sys_devices();
if (freq == 0) {
freq = op_cpu_freq_cpuinfo();
}
return freq;
}