Skip to content

Instantly share code, notes, and snippets.

@computerquip
Last active June 30, 2016 00:11
Show Gist options
  • Save computerquip/5ae2da01322a0ed3f81b to your computer and use it in GitHub Desktop.
Save computerquip/5ae2da01322a0ed3f81b to your computer and use it in GitHub Desktop.
/* 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], &reg[0], &reg[1], &reg[2], &reg[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", &reg[1], &reg[3], &reg[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