From 5bb035c8840a7f1d5672b2c2fa9efdfb037b01ae Mon Sep 17 00:00:00 2001 From: Glavo Date: Sat, 17 May 2025 00:20:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E9=9D=9E=20x86=20=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=20CPU=20=E7=89=A9=E7=90=86=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E6=95=B0=20(#3917)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/platform/linux/LinuxCPUDetector.java | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/linux/LinuxCPUDetector.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/linux/LinuxCPUDetector.java index a948358b2..07fa50ca9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/linux/LinuxCPUDetector.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/linux/LinuxCPUDetector.java @@ -24,14 +24,12 @@ import org.jackhuang.hmcl.util.platform.hardware.CentralProcessor; import org.jackhuang.hmcl.util.platform.hardware.HardwareVendor; import org.jetbrains.annotations.Nullable; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; -import java.util.TreeSet; +import java.util.*; +import java.util.regex.Pattern; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -41,11 +39,9 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG; */ final class LinuxCPUDetector { - private static final String CPUINFO_PATH = "/proc/cpuinfo"; - private static TreeMap> loadCPUInfo() { try { - List> list = KeyValuePairUtils.loadList(Paths.get(CPUINFO_PATH)); + List> list = KeyValuePairUtils.loadList(Paths.get("/proc/cpuinfo")); TreeMap> result = new TreeMap<>(); for (Map map : list) { String id = map.get("processor"); @@ -193,10 +189,50 @@ final class LinuxCPUDetector { return; } } catch (Throwable e) { - LOG.warning("Failed to detect CPU cores", e); + LOG.warning("Failed to detect cores in /proc/cpuinfo", e); + } + + Path cpuDevicesDir = Paths.get("/sys/devices/system/cpu"); + if (Files.isRegularFile(cpuDevicesDir.resolve("cpu0/topology/physical_package_id")) + && Files.isRegularFile(cpuDevicesDir.resolve("cpu0/topology/core_cpus_list"))) { + Pattern dirNamePattern = Pattern.compile("cpu[0-9]+"); + TreeSet physicalPackageIds = new TreeSet<>(); + TreeSet physicalCores = new TreeSet<>(); + + int physical = 0; + try (DirectoryStream stream = Files.newDirectoryStream(cpuDevicesDir)) { + for (Path cpuDir : stream) { + if (!dirNamePattern.matcher(cpuDir.getFileName().toString()).matches() || !Files.isDirectory(cpuDir)) + continue; + + physicalPackageIds.add(Integer.parseInt(FileUtils.readText(cpuDir.resolve("topology/physical_package_id")).trim())); + + boolean shouldCount = false; + for (String item : FileUtils.readText(cpuDir.resolve("topology/core_cpus_list")).trim().split(",")) { + String range = item.trim(); + int idx = range.indexOf('-'); + if (idx < 0) + shouldCount |= physicalCores.add(Integer.parseInt(range)); + else { + int first = Integer.parseInt(range.substring(0, idx)); + int last = Integer.parseInt(range.substring(idx + 1)); + + for (int i = first; i <= last; i++) { + shouldCount |= physicalCores.add(i); + } + } + } + if (shouldCount) + physical++; + } + + builder.setCores(new CentralProcessor.Cores(physical, logical, physicalPackageIds.size())); + return; + } catch (Throwable e) { + LOG.warning("Failed to detect cores in /sys/devices/system/cpu", e); + } } - // We can check /sys/devices/system/cpu, but I don't think it's necessary. builder.setCores(new CentralProcessor.Cores(logical)); }