From 8d10a03adc3515f1f8bc2a03d4d62806346b0e7a Mon Sep 17 00:00:00 2001 From: Er2 Date: Mon, 19 Aug 2024 10:21:41 +0300 Subject: [PATCH] [v1.06][FreeBSD][Apple] Implement fallback frequency calculation (#251) --- Makefile | 4 ++++ src/common/sysctl.h | 8 ++++++++ src/x86/cpuid.c | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a4e5d13..6e7d085 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,10 @@ ifneq ($(OS),Windows_NT) HEADERS += $(SRC_DIR)freq/freq.h CFLAGS += -pthread endif + ifeq ($(os), FreeBSD) + SOURCE += $(SRC_COMMON)sysctl.c + HEADERS += $(SRC_COMMON)sysctl.h + endif CFLAGS += -DARCH_X86 -std=c99 -fstack-protector-all else ifeq ($(arch), $(filter $(arch), ppc64le ppc64 ppcle ppc)) SRC_DIR=src/ppc/ diff --git a/src/common/sysctl.h b/src/common/sysctl.h index f4432ab..32431dd 100644 --- a/src/common/sysctl.h +++ b/src/common/sysctl.h @@ -40,6 +40,14 @@ #define CPUSUBFAMILY_ARM_HC_HD 5 #endif +// For alternative way to get CPU frequency on macOS and *BSD +#ifdef __APPLE__ + #define CPUFREQUENCY_SYSCTL "hw.cpufrequency_max" +#else + // For FreeBSD, not sure about other *BSD + #define CPUFREQUENCY_SYSCTL "dev.cpu.0.freq" +#endif + uint32_t get_sys_info_by_name(char* name); #endif diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 8281a0f..54a120d 100644 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -5,6 +5,9 @@ #include "../common/udev.h" #include #endif +#if defined (__FreeBSD__) || defined (__APPLE__) + #include "../common/sysctl.h" +#endif #ifdef __linux__ #include "../common/freq.h" @@ -938,10 +941,20 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) { freq->measured = false; if(cpu->maxLevels < 0x00000016) { - #if defined (_WIN32) || defined (__APPLE__) + #if defined (_WIN32) printWarn("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000016, cpu->maxLevels); freq->base = UNKNOWN_DATA; freq->max = UNKNOWN_DATA; + #elif defined (__FreeBSD__) || defined (__APPLE__) + printWarn("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X). Using sysctl", 0x00000016, cpu->maxLevels); + uint32_t freq_hz = get_sys_info_by_name(CPUFREQUENCY_SYSCTL); + if (freq_hz == 0) { + printWarn("Read max CPU frequency from sysctl and got 0 MHz"); + freq->max = UNKNOWN_DATA; + } + + freq->base = UNKNOWN_DATA; + freq->max = freq_hz; #else printWarn("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X). Using udev", 0x00000016, cpu->maxLevels); freq->base = UNKNOWN_DATA;