9
0
mirror of https://github.com/Dreeam-qwq/Gale.git synced 2025-12-21 07:49:22 +00:00
Files
Gale/patches/server/0141-CPU-cores-estimation.patch
2022-12-26 07:32:09 +01:00

190 lines
9.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martijn Muijsers <martijnmuijsers@live.nl>
Date: Tue, 29 Nov 2022 12:27:47 +0100
Subject: [PATCH] CPU cores estimation
License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
Gale - https://galemc.org
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index dc9d304257d86109c06ec9b7673d3ee27d5ee875..781fc0a92f73be73b9313e7bc4eeb2f2ed6ff8ea 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -37,6 +37,7 @@ import org.bukkit.configuration.MemorySection;
import org.bukkit.entity.EntityType;
import org.galemc.gale.configuration.GaleGlobalConfiguration;
import org.galemc.gale.configuration.timingsexport.VanillaServerPropertiesTimingsExport;
+import org.galemc.gale.util.CPUCoresEstimation;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import oshi.SystemInfo;
@@ -206,6 +207,10 @@ public class TimingsExport extends Thread {
pair("finalizing", ManagementFactory.getMemoryMXBean().getObjectPendingFinalizationCount())
)),
pair("cpu", runtime.availableProcessors()),
+ // Gale start - CPU cores estimation - include in timings
+ pair("cpucoresestimation", CPUCoresEstimation.get()),
+ pair("cpuphysicalprocessorcount", processor.getPhysicalProcessorCount()),
+ // Gale end - CPU cores estimation - include in timings
pair("cpuname", hardwareInfo.getProcessor().getProcessorIdentifier().getName().trim()),
pair("hardwarespecs", hardwareSpecsMap), // Gale - include hardware specs in timings
pair("runtime", runtimeBean.getUptime()),
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index f5ed3fa20097bdd43a25c76b38353a23743bc9e5..eed9f125df46b616b7234a2d669971bc51bc231b 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -49,6 +49,7 @@ import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.storage.LevelStorageSource;
import org.galemc.gale.command.GaleCommands;
import org.galemc.gale.configuration.GaleGlobalConfiguration;
+import org.galemc.gale.util.CPUCoresEstimation;
import org.slf4j.Logger;
// CraftBukkit start
@@ -226,6 +227,12 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
// Paper end
+ // Gale start - CPU core estimation
+ if (GaleGlobalConfiguration.get().logToConsole.cpuCoresEstimation) {
+ CPUCoresEstimation.log(LOGGER);
+ }
+ // Gale end - CPU core estimation
+
// Gale start - Pufferfish - SIMD support
// Attempt to detect vectorization
try {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index b9a799997e3475117ab91d7f3edb5f2f243a9f6b..e23fdd5ba09b50b7eef0ca4f36c5480779fba624 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -254,6 +254,8 @@ import org.bukkit.scoreboard.Criteria;
import org.bukkit.structure.StructureManager;
import org.bukkit.util.StringUtil;
import org.bukkit.util.permissions.DefaultPermissions;
+import org.galemc.gale.configuration.GaleGlobalConfiguration;
+import org.galemc.gale.util.CPUCoresEstimation;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.MarkedYAMLException;
diff --git a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java
index 48f6e114a3ead68d72f27f9d5572eacbc7613ac3..7a3111603c75105769cf0fc3ff3c5ee6d45b57e5 100644
--- a/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java
+++ b/src/main/java/org/galemc/gale/configuration/GaleGlobalConfiguration.java
@@ -185,6 +185,7 @@ public class GaleGlobalConfiguration extends ConfigurationPart {
public boolean unrecognizedRecipes = false; // Gale - Purpur - do not log unrecognized recipes
public boolean legacyMaterialInitialization = false; // Gale - Purpur - do not log legacy Material initialization
public boolean playerLoginLocations = true; // Gale - JettPack - make logging login location configurable
+ public boolean cpuCoresEstimation = true; // Gale - CPU cores estimation
public Chat chat;
public class Chat extends ConfigurationPart {
diff --git a/src/main/java/org/galemc/gale/util/CPUCoresEstimation.java b/src/main/java/org/galemc/gale/util/CPUCoresEstimation.java
new file mode 100644
index 0000000000000000000000000000000000000000..07020fd1255fade812f4a9af1c76bdd5b7909436
--- /dev/null
+++ b/src/main/java/org/galemc/gale/util/CPUCoresEstimation.java
@@ -0,0 +1,102 @@
+// Gale - CPU cores estimation
+
+package org.galemc.gale.util;
+
+import org.galemc.gale.executor.annotation.thread.AnyThreadSafe;
+import org.galemc.gale.executor.annotation.YieldFree;
+import org.slf4j.Logger;
+import oshi.SystemInfo;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.HardwareAbstractionLayer;
+
+/**
+ * A utility class to estimate the number of physical CPU cores.
+ *
+ * @author Martijn Muijsers under AGPL-3.0
+ */
+@AnyThreadSafe
+@YieldFree
+public final class CPUCoresEstimation {
+
+ private CPUCoresEstimation() {}
+
+ public static final String environmentVariableKey = "gale.cores";
+
+ /**
+ * @return The value of the {@link #environmentVariableKey} environment variable,
+ * or -1 if not set, or -1 if the environment variable is set to a nonpositive value.
+ */
+ public static int getByEnvironmentVariable() {
+ int value = Integer.getInteger(environmentVariableKey, -1);
+ return value > 0 ? value : -1;
+ }
+
+ /**
+ * @return The number of cores estimated by OSHI using {@link CentralProcessor#getPhysicalProcessorCount()},
+ * or -1 if OSHI throws an exception or returns a nonpositive value.
+ */
+ public static int getByOSHI() {
+ try {
+ SystemInfo systemInfo = new SystemInfo();
+ HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
+ CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
+ int coresAccordingToOSHI = centralProcessor.getPhysicalProcessorCount();
+ if (coresAccordingToOSHI > 0) {
+ return coresAccordingToOSHI;
+ }
+ } catch (Throwable ignored) {}
+ return -1;
+ }
+
+ /**
+ * @return A naive estimation of the number of cores, by taking {@link Runtime#availableProcessors()} and applying
+ * floored division by 2, since most systems will have hyper-threading with 2 threads per core. If the result is
+ * nonpositive, this method returns 1.
+ */
+ public static int getByRuntimeProcessors() {
+ return Math.min(1, Runtime.getRuntime().availableProcessors() / 2);
+ }
+
+ public static int get() {
+ // Use the environment variable if set
+ int environmentCores = getByEnvironmentVariable();
+ if (environmentCores > 0) {
+ return environmentCores;
+ }
+ // Use the OSHI library to find the physical processor count
+ int oshiCores = getByOSHI();
+ if (oshiCores > 0) {
+ return oshiCores;
+ }
+ // Make a guess that the number of CPU cores is half the number of available runtime processor
+ // (i.e. guess that the CPU uses hyper-threading with 2 threads per core)
+ return getByRuntimeProcessors();
+ }
+
+ /**
+ * Logs the CPU core estimation to the given {@link Logger}.
+ */
+ public static void log(Logger logger) {
+ String explanation;
+ int assumedValue;
+ // Use the environment variable if set
+ int environmentCores = getByEnvironmentVariable();
+ // Use the OSHI library to find the physical processor count
+ int oshiCores = getByOSHI();
+ if (environmentCores >= 1) {
+ assumedValue = environmentCores;
+ explanation = "(based on the '" + environmentVariableKey + "' environment variable)" + (oshiCores >= 1 ? " (OSHI detected " + oshiCores + " cores)" : "");
+ } else {
+ explanation = "(because ";
+ if (oshiCores >= 1) {
+ assumedValue = oshiCores;
+ explanation += "OSHI detected " + oshiCores + " physical cores)";
+ } else {
+ assumedValue = getByRuntimeProcessors();
+ explanation += "the number of runtime processors is " + Runtime.getRuntime().availableProcessors() + ") (please set the '" + environmentVariableKey + "' environment variable if the number of physical CPU cores is incorrect)";
+ }
+ }
+ logger.info("The server will assume you have " + assumedValue + " physical CPU cores " + explanation + "");
+ }
+
+}