From 9b39ea3230b70077de832da08351946d7b4534dc Mon Sep 17 00:00:00 2001 From: cyy Date: Thu, 10 Aug 2023 17:28:21 +0800 Subject: [PATCH 1/3] Add FreeBSD support --- BUILD.bazel | 17 ++ CMakeLists.txt | 14 +- src/cpuinfo/internal-api.h | 1 + src/freebsd/api.h | 12 ++ src/freebsd/topology.c | 110 ++++++++++ src/init.c | 2 + src/x86/freebsd/init.c | 402 +++++++++++++++++++++++++++++++++++++ 7 files changed, 556 insertions(+), 2 deletions(-) create mode 100644 src/freebsd/api.h create mode 100644 src/freebsd/topology.c create mode 100644 src/x86/freebsd/init.c diff --git a/BUILD.bazel b/BUILD.bazel index 4e3ea999..2c6375fd 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -63,6 +63,10 @@ MACH_SRCS = [ "src/mach/topology.c", ] +FREEBSD_SRCS = [ + "src/freebsd/topology.c", +] + EMSCRIPTEN_SRCS = [ "src/emscripten/init.c", ] @@ -112,6 +116,10 @@ MACH_ARM_SRCS = [ "src/arm/mach/init.c", ] +FREEBSD_X86_SRCS = [ + "src/x86/freebsd/init.c", +] + EMSCRIPTEN_SRCS = [ "src/emscripten/init.c", ] @@ -132,6 +140,7 @@ cc_library( ":macos_x86_64": COMMON_SRCS + X86_SRCS + MACH_SRCS + MACH_X86_SRCS, ":macos_x86_64_legacy": COMMON_SRCS + X86_SRCS + MACH_SRCS + MACH_X86_SRCS, ":macos_arm64": COMMON_SRCS + MACH_SRCS + MACH_ARM_SRCS, + ":freebsd_x86_64": COMMON_SRCS + X86_SRCS + FREEBSD_SRCS + FREEBSD_X86_SRCS, ":windows_x86_64": COMMON_SRCS + X86_SRCS + WINDOWS_X86_SRCS, ":windows_arm64": COMMON_SRCS + ARM_SRCS + WINDOWS_ARM_SRCS, ":android_armv7": COMMON_SRCS + ARM_SRCS + LINUX_SRCS + LINUX_ARM32_SRCS + ANDROID_ARM_SRCS, @@ -175,6 +184,7 @@ cc_library( # Headers must be in textual_hdrs to allow us to set the standard to C99 textual_hdrs = [ "include/cpuinfo.h", + "src/freebsd/api.h", "src/linux/api.h", "src/mach/api.h", "src/cpuinfo/common.h", @@ -463,3 +473,10 @@ config_setting( "cpu": "asmjs", }, ) + +config_setting( + name = "freebsd_x86_64", + values = { + "cpu": "freebsd", + }, +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99047e58..b6dcb740 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,9 @@ ENDIF() # -- [ Determine target processor SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}") +IF(CPUINFO_TARGET_PROCESSOR STREQUAL "amd64") + SET(CPUINFO_TARGET_PROCESSOR "AMD64") +ENDIF() IF(IS_APPLE_OS AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64.*)$") SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}") ELSEIF(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_VS_PLATFORM_NAME) @@ -105,7 +108,7 @@ IF(NOT CMAKE_SYSTEM_NAME) "Target operating system is not specified. " "cpuinfo will compile, but cpuinfo_initialize() will always fail.") SET(CPUINFO_SUPPORTED_PLATFORM FALSE) -ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android)$") +ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android|FreeBSD)$") IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14" AND NOT IS_APPLE_OS) MESSAGE(WARNING "Target operating system \"${CMAKE_SYSTEM_NAME}\" is not supported in cpuinfo. " @@ -178,6 +181,8 @@ IF(CPUINFO_SUPPORTED_PLATFORM) LIST(APPEND CPUINFO_SRCS src/x86/mach/init.c) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS)$") LIST(APPEND CPUINFO_SRCS src/x86/windows/init.c) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + LIST(APPEND CPUINFO_SRCS src/x86/freebsd/init.c) ENDIF() ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^Windows" AND CPUINFO_TARGET_PROCESSOR MATCHES "^(ARM64|arm64)$") LIST(APPEND CPUINFO_SRCS @@ -234,9 +239,11 @@ IF(CPUINFO_SUPPORTED_PLATFORM) src/linux/processors.c) ELSEIF(IS_APPLE_OS) LIST(APPEND CPUINFO_SRCS src/mach/topology.c) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + LIST(APPEND CPUINFO_SRCS src/freebsd/topology.c) ENDIF() - IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) SET(THREADS_PREFER_PTHREAD_FLAG TRUE) FIND_PACKAGE(Threads REQUIRED) @@ -301,6 +308,9 @@ IF(CPUINFO_SUPPORTED_PLATFORM) TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT}) TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _GNU_SOURCE=1) TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _GNU_SOURCE=1) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + TARGET_LINK_LIBRARIES(cpuinfo PUBLIC ${CMAKE_THREAD_LIBS_INIT}) + TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT}) ENDIF() ELSE() TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=0) diff --git a/src/cpuinfo/internal-api.h b/src/cpuinfo/internal-api.h index d566034e..d84b26a8 100644 --- a/src/cpuinfo/internal-api.h +++ b/src/cpuinfo/internal-api.h @@ -49,6 +49,7 @@ extern CPUINFO_INTERNAL const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_ma CPUINFO_PRIVATE void cpuinfo_x86_mach_init(void); CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void); +CPUINFO_PRIVATE void cpuinfo_x86_freebsd_init(void); #if defined(_WIN32) || defined(__CYGWIN__) #if CPUINFO_ARCH_ARM64 CPUINFO_PRIVATE BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context); diff --git a/src/freebsd/api.h b/src/freebsd/api.h new file mode 100644 index 00000000..d3774370 --- /dev/null +++ b/src/freebsd/api.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +struct cpuinfo_freebsd_topology { + uint32_t packages; + uint32_t cores; + uint32_t threads; + uint32_t threads_per_core; +}; + +struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void); diff --git a/src/freebsd/topology.c b/src/freebsd/topology.c new file mode 100644 index 00000000..1885035b --- /dev/null +++ b/src/freebsd/topology.c @@ -0,0 +1,110 @@ +#include +#include +#include + +#include +#include + +#include +#include + +static int sysctl_int(const char *name) { + int value = 0; + size_t value_size = sizeof(value); + if (sysctlbyname(name, &value, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, + strerror(errno)); + } else if (value <= 0) { + cpuinfo_log_error( + "sysctlbyname(\"%s\") returned invalid value %d %zu", name, + value, value_size); + value = 0; + } + return value; +} + +static char *sysctl_str(const char *name) { + size_t value_size = 0; + if (sysctlbyname(name, NULL, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, + strerror(errno)); + } else if (value_size <= 0) { + cpuinfo_log_error( + "sysctlbyname(\"%s\") returned invalid value size %zu", + name, value_size); + } + value_size += 1; + char *value = calloc(value_size, 1); + if (!value) { + cpuinfo_log_error("calloc %zu bytes failed", value_size); + return NULL; + } + if (sysctlbyname(name, value, &value_size, NULL, 0) != 0) { + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, + strerror(errno)); + free(value); + return NULL; + } + return value; +} + +struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { + struct cpuinfo_freebsd_topology topology = { + .packages = 0, + .cores = 0, + .threads_per_core = 0, + .threads = 0, + }; + char *topology_spec = sysctl_str("kern.sched.topology_spec"); + if (!topology_spec) { + return topology; + } + const char *group_tag = ""; + char *p = strstr(topology_spec, group_tag); + while (p) { + const char *cpu_tag = "cpu count=\""; + char *q = strstr(p, cpu_tag); + if (q) { + p = q + strlen(cpu_tag); + topology.packages += atoi(p); + } else { + break; + } + } + if (topology.packages == 0) { + const char *group_tag = " +#include +#include + +#include +#include +#include +#include +#include + +static inline uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; } + +static inline uint32_t bit_mask(uint32_t bits) { + return (UINT32_C(1) << bits) - UINT32_C(1); +} + +void cpuinfo_x86_freebsd_init(void) { + struct cpuinfo_processor *processors = NULL; + struct cpuinfo_core *cores = NULL; + struct cpuinfo_cluster *clusters = NULL; + struct cpuinfo_package *packages = NULL; + struct cpuinfo_cache *l1i = NULL; + struct cpuinfo_cache *l1d = NULL; + struct cpuinfo_cache *l2 = NULL; + struct cpuinfo_cache *l3 = NULL; + struct cpuinfo_cache *l4 = NULL; + + struct cpuinfo_freebsd_topology freebsd_topology = + cpuinfo_freebsd_detect_topology(); + if (freebsd_topology.packages == 0) { + cpuinfo_log_error("failed to detect topology"); + goto cleanup; + } + processors = + calloc(freebsd_topology.threads, sizeof(struct cpuinfo_processor)); + if (processors == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 + " logical processors", + freebsd_topology.threads * sizeof(struct cpuinfo_processor), + freebsd_topology.threads); + goto cleanup; + } + cores = calloc(freebsd_topology.cores, sizeof(struct cpuinfo_core)); + if (cores == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 + " cores", + freebsd_topology.cores * sizeof(struct cpuinfo_core), + freebsd_topology.cores); + goto cleanup; + } + /* On x86 a cluster of cores is the biggest group of cores that shares a + * cache. */ + clusters = + calloc(freebsd_topology.packages, sizeof(struct cpuinfo_cluster)); + if (clusters == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 + " core clusters", + freebsd_topology.packages * sizeof(struct cpuinfo_cluster), + freebsd_topology.packages); + goto cleanup; + } + packages = + calloc(freebsd_topology.packages, sizeof(struct cpuinfo_package)); + if (packages == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of %" PRIu32 + " physical packages", + freebsd_topology.packages * sizeof(struct cpuinfo_package), + freebsd_topology.packages); + goto cleanup; + } + + struct cpuinfo_x86_processor x86_processor; + memset(&x86_processor, 0, sizeof(x86_processor)); + cpuinfo_x86_init_processor(&x86_processor); + char brand_string[48]; + cpuinfo_x86_normalize_brand_string(x86_processor.brand_string, + brand_string); + + const uint32_t threads_per_core = freebsd_topology.threads_per_core; + const uint32_t threads_per_package = + freebsd_topology.threads / freebsd_topology.packages; + const uint32_t cores_per_package = + freebsd_topology.cores / freebsd_topology.packages; + for (uint32_t i = 0; i < freebsd_topology.packages; i++) { + clusters[i] = (struct cpuinfo_cluster){ + .processor_start = i * threads_per_package, + .processor_count = threads_per_package, + .core_start = i * cores_per_package, + .core_count = cores_per_package, + .cluster_id = 0, + .package = packages + i, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + }; + packages[i].processor_start = i * threads_per_package; + packages[i].processor_count = threads_per_package; + packages[i].core_start = i * cores_per_package; + packages[i].core_count = cores_per_package; + packages[i].cluster_start = i; + packages[i].cluster_count = 1; + cpuinfo_x86_format_package_name(x86_processor.vendor, + brand_string, packages[i].name); + } + for (uint32_t i = 0; i < freebsd_topology.cores; i++) { + cores[i] = (struct cpuinfo_core){ + .processor_start = i * threads_per_core, + .processor_count = threads_per_core, + .core_id = i % cores_per_package, + .cluster = clusters + i / cores_per_package, + .package = packages + i / cores_per_package, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + }; + } + for (uint32_t i = 0; i < freebsd_topology.threads; i++) { + const uint32_t smt_id = i % threads_per_core; + const uint32_t core_id = i / threads_per_core; + const uint32_t package_id = i / threads_per_package; + + /* Reconstruct APIC IDs from topology components */ + const uint32_t thread_bits_mask = + bit_mask(x86_processor.topology.thread_bits_length); + const uint32_t core_bits_mask = + bit_mask(x86_processor.topology.core_bits_length); + const uint32_t package_bits_offset = + max(x86_processor.topology.thread_bits_offset + + x86_processor.topology.thread_bits_length, + x86_processor.topology.core_bits_offset + + x86_processor.topology.core_bits_length); + const uint32_t apic_id = + ((smt_id & thread_bits_mask) + << x86_processor.topology.thread_bits_offset) | + ((core_id & core_bits_mask) + << x86_processor.topology.core_bits_offset) | + (package_id << package_bits_offset); + cpuinfo_log_debug("reconstructed APIC ID 0x%08" PRIx32 + " for thread %" PRIu32, + apic_id, i); + + processors[i].smt_id = smt_id; + processors[i].core = cores + i / threads_per_core; + processors[i].cluster = clusters + i / threads_per_package; + processors[i].package = packages + i / threads_per_package; + processors[i].apic_id = apic_id; + } + + uint32_t threads_per_l1 = 0, l1_count = 0; + if (x86_processor.cache.l1i.size != 0 || + x86_processor.cache.l1d.size != 0) { + /* Assume that threads on the same core share L1 */ + threads_per_l1 = + freebsd_topology.threads / freebsd_topology.cores; + cpuinfo_log_warning("freebsd kernel did not report number of " + "threads sharing L1 cache; assume %" PRIu32, + threads_per_l1); + l1_count = freebsd_topology.threads / threads_per_l1; + cpuinfo_log_debug("detected %" PRIu32 " L1 caches", l1_count); + } + + uint32_t threads_per_l2 = 0, l2_count = 0; + if (x86_processor.cache.l2.size != 0) { + if (x86_processor.cache.l3.size != 0) { + /* This is not a last-level cache; assume that threads + * on the same core share L2 */ + threads_per_l2 = + freebsd_topology.threads / freebsd_topology.cores; + } else { + /* This is a last-level cache; assume that threads on + * the same package share L2 */ + threads_per_l2 = freebsd_topology.threads / + freebsd_topology.packages; + } + cpuinfo_log_warning("freebsd kernel did not report number of " + "threads sharing L2 cache; assume %" PRIu32, + threads_per_l2); + l2_count = freebsd_topology.threads / threads_per_l2; + cpuinfo_log_debug("detected %" PRIu32 " L2 caches", l2_count); + } + + uint32_t threads_per_l3 = 0, l3_count = 0; + if (x86_processor.cache.l3.size != 0) { + /* + * Assume that threads on the same package share L3. + * However, is it not necessarily the last-level cache (there + * may be L4 cache as well) + */ + threads_per_l3 = + freebsd_topology.threads / freebsd_topology.packages; + cpuinfo_log_warning("freebsd kernel did not report number of " + "threads sharing L3 cache; assume %" PRIu32, + threads_per_l3); + l3_count = freebsd_topology.threads / threads_per_l3; + cpuinfo_log_debug("detected %" PRIu32 " L3 caches", l3_count); + } + + uint32_t threads_per_l4 = 0, l4_count = 0; + if (x86_processor.cache.l4.size != 0) { + /* + * Assume that all threads share this L4. + * As of now, L4 cache exists only on notebook x86 CPUs, which + * are single-package, but multi-socket systems could have + * shared L4 (like on IBM POWER8). + */ + threads_per_l4 = freebsd_topology.threads; + cpuinfo_log_warning("freebsd kernel did not report number of " + "threads sharing L4 cache; assume %" PRIu32, + threads_per_l4); + l4_count = freebsd_topology.threads / threads_per_l4; + cpuinfo_log_debug("detected %" PRIu32 " L4 caches", l4_count); + } + + if (x86_processor.cache.l1i.size != 0) { + l1i = calloc(l1_count, sizeof(struct cpuinfo_cache)); + if (l1i == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1I caches", + l1_count * sizeof(struct cpuinfo_cache), l1_count); + return; + } + for (uint32_t c = 0; c < l1_count; c++) { + l1i[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l1i.size, + .associativity = + x86_processor.cache.l1i.associativity, + .sets = x86_processor.cache.l1i.sets, + .partitions = x86_processor.cache.l1i.partitions, + .line_size = x86_processor.cache.l1i.line_size, + .flags = x86_processor.cache.l1i.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l1i = &l1i[t / threads_per_l1]; + } + } + + if (x86_processor.cache.l1d.size != 0) { + l1d = calloc(l1_count, sizeof(struct cpuinfo_cache)); + if (l1d == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1D caches", + l1_count * sizeof(struct cpuinfo_cache), l1_count); + return; + } + for (uint32_t c = 0; c < l1_count; c++) { + l1d[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l1d.size, + .associativity = + x86_processor.cache.l1d.associativity, + .sets = x86_processor.cache.l1d.sets, + .partitions = x86_processor.cache.l1d.partitions, + .line_size = x86_processor.cache.l1d.line_size, + .flags = x86_processor.cache.l1d.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l1d = &l1d[t / threads_per_l1]; + } + } + + if (l2_count != 0) { + l2 = calloc(l2_count, sizeof(struct cpuinfo_cache)); + if (l2 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L2 caches", + l2_count * sizeof(struct cpuinfo_cache), l2_count); + return; + } + for (uint32_t c = 0; c < l2_count; c++) { + l2[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l2.size, + .associativity = + x86_processor.cache.l2.associativity, + .sets = x86_processor.cache.l2.sets, + .partitions = x86_processor.cache.l2.partitions, + .line_size = x86_processor.cache.l2.line_size, + .flags = x86_processor.cache.l2.flags, + .processor_start = c * threads_per_l2, + .processor_count = threads_per_l2, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l2 = &l2[t / threads_per_l2]; + } + } + + if (l3_count != 0) { + l3 = calloc(l3_count, sizeof(struct cpuinfo_cache)); + if (l3 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L3 caches", + l3_count * sizeof(struct cpuinfo_cache), l3_count); + return; + } + for (uint32_t c = 0; c < l3_count; c++) { + l3[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l3.size, + .associativity = + x86_processor.cache.l3.associativity, + .sets = x86_processor.cache.l3.sets, + .partitions = x86_processor.cache.l3.partitions, + .line_size = x86_processor.cache.l3.line_size, + .flags = x86_processor.cache.l3.flags, + .processor_start = c * threads_per_l3, + .processor_count = threads_per_l3, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l3 = &l3[t / threads_per_l3]; + } + } + + if (l4_count != 0) { + l4 = calloc(l4_count, sizeof(struct cpuinfo_cache)); + if (l4 == NULL) { + cpuinfo_log_error( + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L4 caches", + l4_count * sizeof(struct cpuinfo_cache), l4_count); + return; + } + for (uint32_t c = 0; c < l4_count; c++) { + l4[c] = (struct cpuinfo_cache){ + .size = x86_processor.cache.l4.size, + .associativity = + x86_processor.cache.l4.associativity, + .sets = x86_processor.cache.l4.sets, + .partitions = x86_processor.cache.l4.partitions, + .line_size = x86_processor.cache.l4.line_size, + .flags = x86_processor.cache.l4.flags, + .processor_start = c * threads_per_l4, + .processor_count = threads_per_l4, + }; + } + for (uint32_t t = 0; t < freebsd_topology.threads; t++) { + processors[t].cache.l4 = &l4[t / threads_per_l4]; + } + } + + /* Commit changes */ + cpuinfo_processors = processors; + cpuinfo_cores = cores; + cpuinfo_clusters = clusters; + cpuinfo_packages = packages; + cpuinfo_cache[cpuinfo_cache_level_1i] = l1i; + cpuinfo_cache[cpuinfo_cache_level_1d] = l1d; + cpuinfo_cache[cpuinfo_cache_level_2] = l2; + cpuinfo_cache[cpuinfo_cache_level_3] = l3; + cpuinfo_cache[cpuinfo_cache_level_4] = l4; + + cpuinfo_processors_count = freebsd_topology.threads; + cpuinfo_cores_count = freebsd_topology.cores; + cpuinfo_clusters_count = freebsd_topology.packages; + cpuinfo_packages_count = freebsd_topology.packages; + cpuinfo_cache_count[cpuinfo_cache_level_1i] = l1_count; + cpuinfo_cache_count[cpuinfo_cache_level_1d] = l1_count; + cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count; + cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count; + cpuinfo_cache_count[cpuinfo_cache_level_4] = l4_count; + cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); + + cpuinfo_global_uarch = (struct cpuinfo_uarch_info){ + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + .processor_count = freebsd_topology.threads, + .core_count = freebsd_topology.cores, + }; + + __sync_synchronize(); + + cpuinfo_is_initialized = true; + + processors = NULL; + cores = NULL; + clusters = NULL; + packages = NULL; + l1i = l1d = l2 = l3 = l4 = NULL; + +cleanup: + free(processors); + free(cores); + free(clusters); + free(packages); + free(l1i); + free(l1d); + free(l2); + free(l3); + free(l4); +} From 63032296f8765821b043e9205597bc6363f0858f Mon Sep 17 00:00:00 2001 From: cyy Date: Sat, 30 Mar 2024 11:37:18 +0800 Subject: [PATCH 2/3] Format code --- src/freebsd/topology.c | 58 ++++---- src/init.c | 2 +- src/x86/freebsd/init.c | 304 +++++++++++++++++++---------------------- 3 files changed, 169 insertions(+), 195 deletions(-) diff --git a/src/freebsd/topology.c b/src/freebsd/topology.c index 1885035b..da941e9c 100644 --- a/src/freebsd/topology.c +++ b/src/freebsd/topology.c @@ -8,40 +8,33 @@ #include #include -static int sysctl_int(const char *name) { +static int sysctl_int(const char* name) { int value = 0; size_t value_size = sizeof(value); if (sysctlbyname(name, &value, &value_size, NULL, 0) != 0) { - cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, - strerror(errno)); + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); } else if (value <= 0) { - cpuinfo_log_error( - "sysctlbyname(\"%s\") returned invalid value %d %zu", name, - value, value_size); + cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value %d %zu", name, value, value_size); value = 0; } return value; } -static char *sysctl_str(const char *name) { +static char* sysctl_str(const char* name) { size_t value_size = 0; if (sysctlbyname(name, NULL, &value_size, NULL, 0) != 0) { - cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, - strerror(errno)); + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); } else if (value_size <= 0) { - cpuinfo_log_error( - "sysctlbyname(\"%s\") returned invalid value size %zu", - name, value_size); + cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value size %zu", name, value_size); } value_size += 1; - char *value = calloc(value_size, 1); + char* value = calloc(value_size, 1); if (!value) { cpuinfo_log_error("calloc %zu bytes failed", value_size); return NULL; } if (sysctlbyname(name, value, &value_size, NULL, 0) != 0) { - cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, - strerror(errno)); + cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno)); free(value); return NULL; } @@ -50,20 +43,20 @@ static char *sysctl_str(const char *name) { struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { struct cpuinfo_freebsd_topology topology = { - .packages = 0, - .cores = 0, - .threads_per_core = 0, - .threads = 0, + .packages = 0, + .cores = 0, + .threads_per_core = 0, + .threads = 0, }; - char *topology_spec = sysctl_str("kern.sched.topology_spec"); + char* topology_spec = sysctl_str("kern.sched.topology_spec"); if (!topology_spec) { return topology; } - const char *group_tag = ""; - char *p = strstr(topology_spec, group_tag); + const char* group_tag = ""; + char* p = strstr(topology_spec, group_tag); while (p) { - const char *cpu_tag = "cpu count=\""; - char *q = strstr(p, cpu_tag); + const char* cpu_tag = "cpu count=\""; + char* q = strstr(p, cpu_tag); if (q) { p = q + strlen(cpu_tag); topology.packages += atoi(p); @@ -72,8 +65,8 @@ struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) { } } if (topology.packages == 0) { - const char *group_tag = " #include -static inline uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; } +static inline uint32_t max(uint32_t a, uint32_t b) { + return a > b ? a : b; +} static inline uint32_t bit_mask(uint32_t bits) { return (UINT32_C(1) << bits) - UINT32_C(1); } void cpuinfo_x86_freebsd_init(void) { - struct cpuinfo_processor *processors = NULL; - struct cpuinfo_core *cores = NULL; - struct cpuinfo_cluster *clusters = NULL; - struct cpuinfo_package *packages = NULL; - struct cpuinfo_cache *l1i = NULL; - struct cpuinfo_cache *l1d = NULL; - struct cpuinfo_cache *l2 = NULL; - struct cpuinfo_cache *l3 = NULL; - struct cpuinfo_cache *l4 = NULL; + struct cpuinfo_processor* processors = NULL; + struct cpuinfo_core* cores = NULL; + struct cpuinfo_cluster* clusters = NULL; + struct cpuinfo_package* packages = NULL; + struct cpuinfo_cache* l1i = NULL; + struct cpuinfo_cache* l1d = NULL; + struct cpuinfo_cache* l2 = NULL; + struct cpuinfo_cache* l3 = NULL; + struct cpuinfo_cache* l4 = NULL; - struct cpuinfo_freebsd_topology freebsd_topology = - cpuinfo_freebsd_detect_topology(); + struct cpuinfo_freebsd_topology freebsd_topology = cpuinfo_freebsd_detect_topology(); if (freebsd_topology.packages == 0) { cpuinfo_log_error("failed to detect topology"); goto cleanup; } - processors = - calloc(freebsd_topology.threads, sizeof(struct cpuinfo_processor)); + processors = calloc(freebsd_topology.threads, sizeof(struct cpuinfo_processor)); if (processors == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of %" PRIu32 - " logical processors", - freebsd_topology.threads * sizeof(struct cpuinfo_processor), - freebsd_topology.threads); + "failed to allocate %zu bytes for descriptions of %" PRIu32 " logical processors", + freebsd_topology.threads * sizeof(struct cpuinfo_processor), + freebsd_topology.threads); goto cleanup; } cores = calloc(freebsd_topology.cores, sizeof(struct cpuinfo_core)); if (cores == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of %" PRIu32 - " cores", - freebsd_topology.cores * sizeof(struct cpuinfo_core), - freebsd_topology.cores); + "failed to allocate %zu bytes for descriptions of %" PRIu32 " cores", + freebsd_topology.cores * sizeof(struct cpuinfo_core), + freebsd_topology.cores); goto cleanup; } /* On x86 a cluster of cores is the biggest group of cores that shares a * cache. */ - clusters = - calloc(freebsd_topology.packages, sizeof(struct cpuinfo_cluster)); + clusters = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_cluster)); if (clusters == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of %" PRIu32 - " core clusters", - freebsd_topology.packages * sizeof(struct cpuinfo_cluster), - freebsd_topology.packages); + "failed to allocate %zu bytes for descriptions of %" PRIu32 " core clusters", + freebsd_topology.packages * sizeof(struct cpuinfo_cluster), + freebsd_topology.packages); goto cleanup; } - packages = - calloc(freebsd_topology.packages, sizeof(struct cpuinfo_package)); + packages = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_package)); if (packages == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of %" PRIu32 - " physical packages", - freebsd_topology.packages * sizeof(struct cpuinfo_package), - freebsd_topology.packages); + "failed to allocate %zu bytes for descriptions of %" PRIu32 " physical packages", + freebsd_topology.packages * sizeof(struct cpuinfo_package), + freebsd_topology.packages); goto cleanup; } @@ -77,25 +71,22 @@ void cpuinfo_x86_freebsd_init(void) { memset(&x86_processor, 0, sizeof(x86_processor)); cpuinfo_x86_init_processor(&x86_processor); char brand_string[48]; - cpuinfo_x86_normalize_brand_string(x86_processor.brand_string, - brand_string); + cpuinfo_x86_normalize_brand_string(x86_processor.brand_string, brand_string); const uint32_t threads_per_core = freebsd_topology.threads_per_core; - const uint32_t threads_per_package = - freebsd_topology.threads / freebsd_topology.packages; - const uint32_t cores_per_package = - freebsd_topology.cores / freebsd_topology.packages; + const uint32_t threads_per_package = freebsd_topology.threads / freebsd_topology.packages; + const uint32_t cores_per_package = freebsd_topology.cores / freebsd_topology.packages; for (uint32_t i = 0; i < freebsd_topology.packages; i++) { clusters[i] = (struct cpuinfo_cluster){ - .processor_start = i * threads_per_package, - .processor_count = threads_per_package, - .core_start = i * cores_per_package, - .core_count = cores_per_package, - .cluster_id = 0, - .package = packages + i, - .vendor = x86_processor.vendor, - .uarch = x86_processor.uarch, - .cpuid = x86_processor.cpuid, + .processor_start = i * threads_per_package, + .processor_count = threads_per_package, + .core_start = i * cores_per_package, + .core_count = cores_per_package, + .cluster_id = 0, + .package = packages + i, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, }; packages[i].processor_start = i * threads_per_package; packages[i].processor_count = threads_per_package; @@ -103,19 +94,18 @@ void cpuinfo_x86_freebsd_init(void) { packages[i].core_count = cores_per_package; packages[i].cluster_start = i; packages[i].cluster_count = 1; - cpuinfo_x86_format_package_name(x86_processor.vendor, - brand_string, packages[i].name); + cpuinfo_x86_format_package_name(x86_processor.vendor, brand_string, packages[i].name); } for (uint32_t i = 0; i < freebsd_topology.cores; i++) { cores[i] = (struct cpuinfo_core){ - .processor_start = i * threads_per_core, - .processor_count = threads_per_core, - .core_id = i % cores_per_package, - .cluster = clusters + i / cores_per_package, - .package = packages + i / cores_per_package, - .vendor = x86_processor.vendor, - .uarch = x86_processor.uarch, - .cpuid = x86_processor.cpuid, + .processor_start = i * threads_per_core, + .processor_count = threads_per_core, + .core_id = i % cores_per_package, + .cluster = clusters + i / cores_per_package, + .package = packages + i / cores_per_package, + .vendor = x86_processor.vendor, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, }; } for (uint32_t i = 0; i < freebsd_topology.threads; i++) { @@ -124,24 +114,15 @@ void cpuinfo_x86_freebsd_init(void) { const uint32_t package_id = i / threads_per_package; /* Reconstruct APIC IDs from topology components */ - const uint32_t thread_bits_mask = - bit_mask(x86_processor.topology.thread_bits_length); - const uint32_t core_bits_mask = - bit_mask(x86_processor.topology.core_bits_length); + const uint32_t thread_bits_mask = bit_mask(x86_processor.topology.thread_bits_length); + const uint32_t core_bits_mask = bit_mask(x86_processor.topology.core_bits_length); const uint32_t package_bits_offset = - max(x86_processor.topology.thread_bits_offset + - x86_processor.topology.thread_bits_length, - x86_processor.topology.core_bits_offset + - x86_processor.topology.core_bits_length); - const uint32_t apic_id = - ((smt_id & thread_bits_mask) - << x86_processor.topology.thread_bits_offset) | - ((core_id & core_bits_mask) - << x86_processor.topology.core_bits_offset) | - (package_id << package_bits_offset); - cpuinfo_log_debug("reconstructed APIC ID 0x%08" PRIx32 - " for thread %" PRIu32, - apic_id, i); + max(x86_processor.topology.thread_bits_offset + x86_processor.topology.thread_bits_length, + x86_processor.topology.core_bits_offset + x86_processor.topology.core_bits_length); + const uint32_t apic_id = ((smt_id & thread_bits_mask) << x86_processor.topology.thread_bits_offset) | + ((core_id & core_bits_mask) << x86_processor.topology.core_bits_offset) | + (package_id << package_bits_offset); + cpuinfo_log_debug("reconstructed APIC ID 0x%08" PRIx32 " for thread %" PRIu32, apic_id, i); processors[i].smt_id = smt_id; processors[i].core = cores + i / threads_per_core; @@ -151,14 +132,13 @@ void cpuinfo_x86_freebsd_init(void) { } uint32_t threads_per_l1 = 0, l1_count = 0; - if (x86_processor.cache.l1i.size != 0 || - x86_processor.cache.l1d.size != 0) { + if (x86_processor.cache.l1i.size != 0 || x86_processor.cache.l1d.size != 0) { /* Assume that threads on the same core share L1 */ - threads_per_l1 = - freebsd_topology.threads / freebsd_topology.cores; - cpuinfo_log_warning("freebsd kernel did not report number of " - "threads sharing L1 cache; assume %" PRIu32, - threads_per_l1); + threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores; + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L1 cache; assume %" PRIu32, + threads_per_l1); l1_count = freebsd_topology.threads / threads_per_l1; cpuinfo_log_debug("detected %" PRIu32 " L1 caches", l1_count); } @@ -168,17 +148,16 @@ void cpuinfo_x86_freebsd_init(void) { if (x86_processor.cache.l3.size != 0) { /* This is not a last-level cache; assume that threads * on the same core share L2 */ - threads_per_l2 = - freebsd_topology.threads / freebsd_topology.cores; + threads_per_l2 = freebsd_topology.threads / freebsd_topology.cores; } else { /* This is a last-level cache; assume that threads on * the same package share L2 */ - threads_per_l2 = freebsd_topology.threads / - freebsd_topology.packages; + threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages; } - cpuinfo_log_warning("freebsd kernel did not report number of " - "threads sharing L2 cache; assume %" PRIu32, - threads_per_l2); + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L2 cache; assume %" PRIu32, + threads_per_l2); l2_count = freebsd_topology.threads / threads_per_l2; cpuinfo_log_debug("detected %" PRIu32 " L2 caches", l2_count); } @@ -190,11 +169,11 @@ void cpuinfo_x86_freebsd_init(void) { * However, is it not necessarily the last-level cache (there * may be L4 cache as well) */ - threads_per_l3 = - freebsd_topology.threads / freebsd_topology.packages; - cpuinfo_log_warning("freebsd kernel did not report number of " - "threads sharing L3 cache; assume %" PRIu32, - threads_per_l3); + threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages; + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L3 cache; assume %" PRIu32, + threads_per_l3); l3_count = freebsd_topology.threads / threads_per_l3; cpuinfo_log_debug("detected %" PRIu32 " L3 caches", l3_count); } @@ -208,9 +187,10 @@ void cpuinfo_x86_freebsd_init(void) { * shared L4 (like on IBM POWER8). */ threads_per_l4 = freebsd_topology.threads; - cpuinfo_log_warning("freebsd kernel did not report number of " - "threads sharing L4 cache; assume %" PRIu32, - threads_per_l4); + cpuinfo_log_warning( + "freebsd kernel did not report number of " + "threads sharing L4 cache; assume %" PRIu32, + threads_per_l4); l4_count = freebsd_topology.threads / threads_per_l4; cpuinfo_log_debug("detected %" PRIu32 " L4 caches", l4_count); } @@ -219,22 +199,22 @@ void cpuinfo_x86_freebsd_init(void) { l1i = calloc(l1_count, sizeof(struct cpuinfo_cache)); if (l1i == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of " - "%" PRIu32 " L1I caches", - l1_count * sizeof(struct cpuinfo_cache), l1_count); + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1I caches", + l1_count * sizeof(struct cpuinfo_cache), + l1_count); return; } for (uint32_t c = 0; c < l1_count; c++) { l1i[c] = (struct cpuinfo_cache){ - .size = x86_processor.cache.l1i.size, - .associativity = - x86_processor.cache.l1i.associativity, - .sets = x86_processor.cache.l1i.sets, - .partitions = x86_processor.cache.l1i.partitions, - .line_size = x86_processor.cache.l1i.line_size, - .flags = x86_processor.cache.l1i.flags, - .processor_start = c * threads_per_l1, - .processor_count = threads_per_l1, + .size = x86_processor.cache.l1i.size, + .associativity = x86_processor.cache.l1i.associativity, + .sets = x86_processor.cache.l1i.sets, + .partitions = x86_processor.cache.l1i.partitions, + .line_size = x86_processor.cache.l1i.line_size, + .flags = x86_processor.cache.l1i.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, }; } for (uint32_t t = 0; t < freebsd_topology.threads; t++) { @@ -246,22 +226,22 @@ void cpuinfo_x86_freebsd_init(void) { l1d = calloc(l1_count, sizeof(struct cpuinfo_cache)); if (l1d == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of " - "%" PRIu32 " L1D caches", - l1_count * sizeof(struct cpuinfo_cache), l1_count); + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L1D caches", + l1_count * sizeof(struct cpuinfo_cache), + l1_count); return; } for (uint32_t c = 0; c < l1_count; c++) { l1d[c] = (struct cpuinfo_cache){ - .size = x86_processor.cache.l1d.size, - .associativity = - x86_processor.cache.l1d.associativity, - .sets = x86_processor.cache.l1d.sets, - .partitions = x86_processor.cache.l1d.partitions, - .line_size = x86_processor.cache.l1d.line_size, - .flags = x86_processor.cache.l1d.flags, - .processor_start = c * threads_per_l1, - .processor_count = threads_per_l1, + .size = x86_processor.cache.l1d.size, + .associativity = x86_processor.cache.l1d.associativity, + .sets = x86_processor.cache.l1d.sets, + .partitions = x86_processor.cache.l1d.partitions, + .line_size = x86_processor.cache.l1d.line_size, + .flags = x86_processor.cache.l1d.flags, + .processor_start = c * threads_per_l1, + .processor_count = threads_per_l1, }; } for (uint32_t t = 0; t < freebsd_topology.threads; t++) { @@ -273,22 +253,22 @@ void cpuinfo_x86_freebsd_init(void) { l2 = calloc(l2_count, sizeof(struct cpuinfo_cache)); if (l2 == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of " - "%" PRIu32 " L2 caches", - l2_count * sizeof(struct cpuinfo_cache), l2_count); + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L2 caches", + l2_count * sizeof(struct cpuinfo_cache), + l2_count); return; } for (uint32_t c = 0; c < l2_count; c++) { l2[c] = (struct cpuinfo_cache){ - .size = x86_processor.cache.l2.size, - .associativity = - x86_processor.cache.l2.associativity, - .sets = x86_processor.cache.l2.sets, - .partitions = x86_processor.cache.l2.partitions, - .line_size = x86_processor.cache.l2.line_size, - .flags = x86_processor.cache.l2.flags, - .processor_start = c * threads_per_l2, - .processor_count = threads_per_l2, + .size = x86_processor.cache.l2.size, + .associativity = x86_processor.cache.l2.associativity, + .sets = x86_processor.cache.l2.sets, + .partitions = x86_processor.cache.l2.partitions, + .line_size = x86_processor.cache.l2.line_size, + .flags = x86_processor.cache.l2.flags, + .processor_start = c * threads_per_l2, + .processor_count = threads_per_l2, }; } for (uint32_t t = 0; t < freebsd_topology.threads; t++) { @@ -300,22 +280,22 @@ void cpuinfo_x86_freebsd_init(void) { l3 = calloc(l3_count, sizeof(struct cpuinfo_cache)); if (l3 == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of " - "%" PRIu32 " L3 caches", - l3_count * sizeof(struct cpuinfo_cache), l3_count); + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L3 caches", + l3_count * sizeof(struct cpuinfo_cache), + l3_count); return; } for (uint32_t c = 0; c < l3_count; c++) { l3[c] = (struct cpuinfo_cache){ - .size = x86_processor.cache.l3.size, - .associativity = - x86_processor.cache.l3.associativity, - .sets = x86_processor.cache.l3.sets, - .partitions = x86_processor.cache.l3.partitions, - .line_size = x86_processor.cache.l3.line_size, - .flags = x86_processor.cache.l3.flags, - .processor_start = c * threads_per_l3, - .processor_count = threads_per_l3, + .size = x86_processor.cache.l3.size, + .associativity = x86_processor.cache.l3.associativity, + .sets = x86_processor.cache.l3.sets, + .partitions = x86_processor.cache.l3.partitions, + .line_size = x86_processor.cache.l3.line_size, + .flags = x86_processor.cache.l3.flags, + .processor_start = c * threads_per_l3, + .processor_count = threads_per_l3, }; } for (uint32_t t = 0; t < freebsd_topology.threads; t++) { @@ -327,22 +307,22 @@ void cpuinfo_x86_freebsd_init(void) { l4 = calloc(l4_count, sizeof(struct cpuinfo_cache)); if (l4 == NULL) { cpuinfo_log_error( - "failed to allocate %zu bytes for descriptions of " - "%" PRIu32 " L4 caches", - l4_count * sizeof(struct cpuinfo_cache), l4_count); + "failed to allocate %zu bytes for descriptions of " + "%" PRIu32 " L4 caches", + l4_count * sizeof(struct cpuinfo_cache), + l4_count); return; } for (uint32_t c = 0; c < l4_count; c++) { l4[c] = (struct cpuinfo_cache){ - .size = x86_processor.cache.l4.size, - .associativity = - x86_processor.cache.l4.associativity, - .sets = x86_processor.cache.l4.sets, - .partitions = x86_processor.cache.l4.partitions, - .line_size = x86_processor.cache.l4.line_size, - .flags = x86_processor.cache.l4.flags, - .processor_start = c * threads_per_l4, - .processor_count = threads_per_l4, + .size = x86_processor.cache.l4.size, + .associativity = x86_processor.cache.l4.associativity, + .sets = x86_processor.cache.l4.sets, + .partitions = x86_processor.cache.l4.partitions, + .line_size = x86_processor.cache.l4.line_size, + .flags = x86_processor.cache.l4.flags, + .processor_start = c * threads_per_l4, + .processor_count = threads_per_l4, }; } for (uint32_t t = 0; t < freebsd_topology.threads; t++) { @@ -373,10 +353,10 @@ void cpuinfo_x86_freebsd_init(void) { cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); cpuinfo_global_uarch = (struct cpuinfo_uarch_info){ - .uarch = x86_processor.uarch, - .cpuid = x86_processor.cpuid, - .processor_count = freebsd_topology.threads, - .core_count = freebsd_topology.cores, + .uarch = x86_processor.uarch, + .cpuid = x86_processor.cpuid, + .processor_count = freebsd_topology.threads, + .core_count = freebsd_topology.cores, }; __sync_synchronize(); From 33611047e330f468899395087349084a5e88aa7d Mon Sep 17 00:00:00 2001 From: cyy Date: Sat, 30 Mar 2024 11:45:49 +0800 Subject: [PATCH 3/3] Improve platform detection in CMake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6dcb740..e505e5a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ ENDIF() # -- [ Determine target processor SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}") -IF(CPUINFO_TARGET_PROCESSOR STREQUAL "amd64") +IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND CPUINFO_TARGET_PROCESSOR STREQUAL "amd64") SET(CPUINFO_TARGET_PROCESSOR "AMD64") ENDIF() IF(IS_APPLE_OS AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64.*)$")