Last active
June 30, 2016 00:11
-
-
Save computerquip/5ae2da01322a0ed3f81b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This file is to be compiled only on X86 systems. | |
The build system should figure this out for us. | |
reg[4] represent the registers eax, ebx, ecx, and edx respectively. */ | |
#include <stdio.h> | |
#include <string.h> | |
#include <errno.h> | |
#if defined (__clang__) || (__GNUC__) | |
#include <cpuid.h> | |
static void obs_cpuid(unsigned reg[4]) | |
{ | |
__get_cpuid(reg[0], ®[0], ®[1], ®[2], ®[3]); | |
} | |
#elif defined (_MSC_VER) | |
#include <intrin.h> | |
static void obs_cpuid(unsigned reg[4]) | |
{ | |
__cpuidex(reg, reg[0], reg[3]); /* Output to reg, send eax and ecx */ | |
} | |
#endif | |
static void parse_cpufrequency_sysfs(unsigned core) | |
{ | |
unsigned frequency = 0; | |
/* 10 is maximum width of an unsigned integer. */ | |
char buffer[sizeof("/sys/devices/system/cpu/cpu/cpufreq/scaling_cur_freq\0") + 10]; | |
sprintf(buffer, "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", core); | |
{ | |
FILE* file = fopen(buffer, "r"); | |
int result; | |
if (!file) { | |
printf("Unable to open %s for parsing: %s\n", buffer, strerror(errno)); | |
return; | |
} | |
result = fscanf(file, "%u", &frequency); | |
if (result <= 0) { | |
printf("File %s was either empty or an error occured while reading.\n", buffer); | |
buffer; | |
} | |
printf("(CPU #%u) Current Frequency: %fMhz\n", core, frequency * .001); | |
} | |
} | |
static void parse_cpucount_sysfs() | |
{ | |
const char online_filepath[] = "/sys/devices/system/cpu/online"; | |
int prev = -1; /* Not 0 as 0 is a valid value. */ | |
int num_cores = 0; | |
/* file_num_online contains the number of cores online (not all possible) across various CPUs. */ | |
FILE* file = fopen(online_filepath, "r"); | |
if (!file) { | |
printf("You got problems son. Most likely, you're missing an important scheduling module.\n"); | |
return; | |
} | |
/* The following is similar to what's found in glibc for fetching number of online processors. */ | |
for (;;) { | |
char sep; | |
int cpu; | |
int n = fscanf(file, "%u%c", &cpu, &sep); | |
if (n <= 0) | |
break; | |
if (n == 1) /* There was no seperator... meaning eol.*/ | |
sep = '\n'; | |
if (prev >= 0) { /* This is the second number in a range, for sure higher than the last. */ | |
for (int i = prev; i <= cpu; ++i) { | |
parse_cpufrequency_sysfs(i); | |
++num_cores; | |
} | |
prev = -1; | |
} else if (sep == '-') { | |
prev = cpu; | |
} else { | |
parse_cpufrequency_sysfs(cpu); | |
++num_cores; | |
} | |
if (sep == '\n') break; | |
} | |
} | |
void print_cpu_vendor() | |
{ | |
unsigned reg[4] = { 0, 0, 0, 0 }; | |
obs_cpuid(reg); | |
printf("Vendor: %.4s%.4s%.4s\n", ®[1], ®[3], ®[2]); | |
} | |
int main() | |
{ | |
print_cpu_vendor(); | |
parse_cpucount_sysfs(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment