diff --git a/Makefile b/Makefile index a4f98d2..e82fd2e 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,12 @@ SANITY_FLAGS=-Wfloat-equal -Wshadow -Wpointer-arith -Wstrict-overflow=5 -Wformat SRC_DIR=src/ SOURCE=$(SRC_DIR)main.c $(SRC_DIR)standart.c $(SRC_DIR)extended.c $(SRC_DIR)cpuid.c $(SRC_DIR)printer.c $(SRC_DIR)args.c $(SRC_DIR)global.c -HEADERS=$(SRC_DIR)standart.h $(SRC_DIR)extended.h $(SRC_DIR)cpuid.h $(SRC_DIR)printer.h $(SRC_DIR)ascii.h $(SRC_DIR)args.h $(SRC_DIR)global.h +HEADERS=$(SRC_DIR)standart.h $(SRC_DIR)extended.h $(SRC_DIR)cpuid.h $(SRC_DIR)printer.h $(SRC_DIR)ascii.h $(SRC_DIR)args.h $(SRC_DIR)global.h + +ifneq ($(OS),Windows_NT) + SOURCE += $(SRC_DIR)udev.c + HEADERS += $(SRC_DIR)udev.h +endif OUTPUT=cpufetch diff --git a/src/main.c b/src/main.c index 56121f3..7dbc0b6 100644 --- a/src/main.c +++ b/src/main.c @@ -24,7 +24,7 @@ Peak FLOPS: 512 GFLOP/s(in simple precision) ***/ -static const char* VERSION = "0.45"; +static const char* VERSION = "0.46"; void print_help(int argc, char *argv[]) { printf("Usage: %s [--version] [--help] [--style STYLE]\n\ diff --git a/src/standart.c b/src/standart.c index 671345a..e8c670e 100644 --- a/src/standart.c +++ b/src/standart.c @@ -9,6 +9,10 @@ #include "cpuid.h" #include "global.h" +#ifndef _WIN32 +#include "udev.h" +#endif + #define VENDOR_INTEL_STRING "GenuineIntel" #define VENDOR_AMD_STRING "AuthenticAMD" @@ -21,8 +25,6 @@ #define STRING_KILOBYTES "KB" #define STRING_MEGABYTES "MB" -#define UNKNOWN -1 - /* * cpuid reference: http://www.sandpile.org/x86/cpuid.htm */ @@ -346,9 +348,15 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) { struct frequency* freq = malloc(sizeof(struct frequency)); if(cpu->maxLevels < 0x16) { - printErr("Can't read frequency information from cpuid (needed level is %d, max is %d)", 0x16, cpu->maxLevels); - freq->base = UNKNOWN; - freq->max = UNKNOWN; + #ifdef _WIN32 + printErr("Can't read frequency information from cpuid (needed level is %d, max is %d)", 0x16, cpu->maxLevels); + freq->base = UNKNOWN; + freq->max = UNKNOWN; + #else + printWarn("Can't read frequency information from cpuid (needed level is %d, max is %d). Using udev", 0x16, cpu->maxLevels); + freq->base = 0; + freq->max = get_max_freq_from_file(); + #endif } else { unsigned int eax = 0x16; @@ -359,7 +367,7 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) { cpuid(&eax, &ebx, &ecx, &edx); freq->base = eax; - freq->max = ebx; + freq->max = ebx; } return freq; @@ -436,7 +444,7 @@ char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, long // Intel USUALLY has two VPUs. I have never seen an AMD // with two VPUs. - if(cpu->VENDOR == VENDOR_INTEL) flops = flops * 2; + if(cpu->cpu_vendor == VENDOR_INTEL) flops = flops * 2; if(cpu->FMA3 || cpu->FMA4) flops = flops*2; diff --git a/src/standart.h b/src/standart.h index 2eb131d..c3a507b 100644 --- a/src/standart.h +++ b/src/standart.h @@ -6,6 +6,8 @@ #define VENDOR_AMD 2 #define VENDOR_INVALID 3 +#define UNKNOWN -1 + struct cpuInfo; struct frequency; struct cache; diff --git a/src/udev.c b/src/udev.c new file mode 100644 index 0000000..5403f8e --- /dev/null +++ b/src/udev.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#include "global.h" +#include "standart.h" + +#define _PATH_SYS_SYSTEM "/sys/devices/system" +#define _PATH_SYS_CPU _PATH_SYS_SYSTEM"/cpu" +#define _PATH_ONE_CPU _PATH_SYS_CPU"/cpu0" + +#define _PATH_FREQUENCY _PATH_ONE_CPU"/cpufreq" +#define _PATH_FREQUENCY_MAX _PATH_FREQUENCY"/cpuinfo_max_freq" +#define _PATH_FREQUENCY_MIN _PATH_FREQUENCY"/cpuinfo_min_freq" + +#define DEFAULT_FILE_SIZE 4096 + +long get_freq_from_file(char* path) { + FILE *file = fopen(path, "r"); + + if(file == NULL) { + perror("fopen"); + printBug("Could not open '%s'", path); + return UNKNOWN; + } + + //File exists, read it + int fd = fileno(file); + int bytes_read = 0; + int offset = 0; + int block = 1; + char* buf = malloc(sizeof(char)*DEFAULT_FILE_SIZE); + memset(buf, 0, sizeof(char)*DEFAULT_FILE_SIZE); + + while ( (bytes_read = read(fd, buf+offset, block)) > 0 ) { + offset += bytes_read; + } + + char* end; + errno = 0; + long ret = strtol(buf, &end, 10); + if(errno != 0) { + perror("strtol"); + printBug("Failed parsing '%s' file. Read data was: '%s'", path, buf); + free(buf); + return UNKNOWN; + } + + // We will be getting the frequency in KHz + // We consider it is an error if frequency is + // greater than 10 GHz or less than 100 MHz + if(ret > 10000 * 1000 || ret < 100 * 1000) { + printBug("Invalid data was read from file '%s': %ld\n", path, ret); + return UNKNOWN; + } + + free(buf); + fclose(file); + + return ret/1000; +} + +long get_max_freq_from_file() { + return get_freq_from_file(_PATH_FREQUENCY_MAX); +} + +long get_min_freq_from_file() { + return get_freq_from_file(_PATH_FREQUENCY_MIN); +} diff --git a/src/udev.h b/src/udev.h new file mode 100644 index 0000000..3517b2e --- /dev/null +++ b/src/udev.h @@ -0,0 +1,7 @@ +#ifndef __UDEV__ +#define __UDEV__ + +long get_max_freq_from_file(); +long get_min_freq_from_file(); + +#endif