linux: use /proc/cpuinfo for CPU frequency
Obtain the CPU frequency from /proc/cpuinfo because there may not be any cpufreq info available in /sys. This also means that the reported CPU speed from now on is the *maximum* speed, not the *actual* speed the CPU runs at. This change only applies to x86 because ARM and MIPS don't report that information in /proc/cpuinfo. Fixes #588.
This commit is contained in:
parent
1bb1ba27dd
commit
775064a3a5
@ -339,10 +339,13 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|||||||
if (ci == NULL)
|
if (ci == NULL)
|
||||||
return uv__new_sys_error(ENOMEM);
|
return uv__new_sys_error(ENOMEM);
|
||||||
|
|
||||||
read_speeds(numcpus, ci);
|
|
||||||
read_models(numcpus, ci);
|
read_models(numcpus, ci);
|
||||||
read_times(numcpus, ci);
|
read_times(numcpus, ci);
|
||||||
|
|
||||||
|
/* read_models() on x86 also reads the CPU speed from /proc/cpuinfo */
|
||||||
|
if (ci[0].speed == 0)
|
||||||
|
read_speeds(numcpus, ci);
|
||||||
|
|
||||||
*cpu_infos = ci;
|
*cpu_infos = ci;
|
||||||
*count = numcpus;
|
*count = numcpus;
|
||||||
|
|
||||||
@ -358,18 +361,26 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Also reads the CPU frequency on x86. The other architectures only have
|
||||||
|
* a BogoMIPS field, which may not be very accurate.
|
||||||
|
*/
|
||||||
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
static const char marker[] = "model name\t: ";
|
static const char model_marker[] = "model name\t: ";
|
||||||
|
static const char speed_marker[] = "cpu MHz\t\t: ";
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
static const char marker[] = "Processor\t: ";
|
static const char model_marker[] = "Processor\t: ";
|
||||||
|
static const char speed_marker[] = "";
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
static const char marker[] = "cpu model\t\t: ";
|
static const char model_marker[] = "cpu model\t\t: ";
|
||||||
|
static const char speed_marker[] = "";
|
||||||
#else
|
#else
|
||||||
# warning uv_cpu_info() is not supported on this architecture.
|
# warning uv_cpu_info() is not supported on this architecture.
|
||||||
static const char marker[] = "(dummy)";
|
static const char model_marker[] = "";
|
||||||
|
static const char speed_marker[] = "";
|
||||||
#endif
|
#endif
|
||||||
unsigned int num;
|
unsigned int model_idx;
|
||||||
|
unsigned int speed_idx;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char* model;
|
char* model;
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
@ -378,18 +389,27 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
|||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
num = 0;
|
model_idx = 0;
|
||||||
|
speed_idx = 0;
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), fp)) {
|
while (fgets(buf, sizeof(buf), fp)) {
|
||||||
if (num >= numcpus)
|
if (model_marker[0] != '\0' &&
|
||||||
break;
|
model_idx < numcpus &&
|
||||||
|
strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0)
|
||||||
if (strncmp(buf, marker, sizeof(marker) - 1))
|
{
|
||||||
|
model = buf + sizeof(model_marker) - 1;
|
||||||
|
model = strndup(model, strlen(model) - 1); /* strip newline */
|
||||||
|
ci[model_idx++].model = model;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
model = buf + sizeof(marker) - 1;
|
if (speed_marker[0] != '\0' &&
|
||||||
model = strndup(model, strlen(model) - 1); /* strip newline */
|
speed_idx < numcpus &&
|
||||||
ci[num++].model = model;
|
strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0)
|
||||||
|
{
|
||||||
|
ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user