From e2b3c1b2275d55bf12f2b828d177f86536a959f2 Mon Sep 17 00:00:00 2001 From: MartijnMuijsers Date: Tue, 29 Nov 2022 14:26:09 +0100 Subject: [PATCH] Remove more executors --- ....patch => 0060-CPU-cores-estimation.patch} | 0 ... 0061-Add-centralized-AsyncExecutor.patch} | 23 ++++-- .../0062-Remove-Paper-async-executor.patch | 68 ++++++++++++++++ .../0063-Remove-Paper-cleaner-executor.patch | 27 +++++++ .../0064-Remove-background-executor.patch | 78 +++++++++++++++++++ ...h => 0065-Remove-bootstrap-executor.patch} | 8 +- 6 files changed, 194 insertions(+), 10 deletions(-) rename patches/server/{0061-CPU-cores-estimation.patch => 0060-CPU-cores-estimation.patch} (100%) rename patches/server/{0062-Add-centralized-AsyncExecutor.patch => 0061-Add-centralized-AsyncExecutor.patch} (77%) create mode 100644 patches/server/0062-Remove-Paper-async-executor.patch create mode 100644 patches/server/0063-Remove-Paper-cleaner-executor.patch create mode 100644 patches/server/0064-Remove-background-executor.patch rename patches/server/{0060-Remove-bootstrap-executor.patch => 0065-Remove-bootstrap-executor.patch} (81%) diff --git a/patches/server/0061-CPU-cores-estimation.patch b/patches/server/0060-CPU-cores-estimation.patch similarity index 100% rename from patches/server/0061-CPU-cores-estimation.patch rename to patches/server/0060-CPU-cores-estimation.patch diff --git a/patches/server/0062-Add-centralized-AsyncExecutor.patch b/patches/server/0061-Add-centralized-AsyncExecutor.patch similarity index 77% rename from patches/server/0062-Add-centralized-AsyncExecutor.patch rename to patches/server/0061-Add-centralized-AsyncExecutor.patch index f7b84f2..c5f5634 100644 --- a/patches/server/0062-Add-centralized-AsyncExecutor.patch +++ b/patches/server/0061-Add-centralized-AsyncExecutor.patch @@ -7,14 +7,16 @@ License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html) diff --git a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java new file mode 100644 -index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59e76e15d7 +index 0000000000000000000000000000000000000000..de182b9473963b95085fa612f70884a56765ae43 --- /dev/null +++ b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java -@@ -0,0 +1,92 @@ +@@ -0,0 +1,103 @@ +// Gale - centralized async execution + +package org.galemc.gale.concurrent; + ++import com.google.common.util.concurrent.ThreadFactoryBuilder; ++import net.minecraft.Util; +import org.galemc.gale.util.CPUCoresEstimation; + +import java.util.concurrent.BlockingQueue; @@ -25,7 +27,8 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59 +import java.util.concurrent.locks.ReentrantLock; + +/** -+ * An executor for tasks that can run asynchronously. ++ * An executor for tasks that can run asynchronously. This executor uses a fixed thread pool, and as such ++ * is not appropriate for tasks that block. + *
+ * It can be paused when all CPU cores may be needed for something else. + * @@ -41,7 +44,11 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59 + *
+ * This value is at least 1. + */ -+ public static final int parallelism = Math.max(1, Integer.getInteger("gale.threads.async", CPUCoresEstimation.get() - 2)); ++ public static final int parallelism; ++ static { ++ int parallelismByEnvironmentVariable = Integer.getInteger("gale.threads.async", -1); ++ parallelism = Math.max(1, parallelismByEnvironmentVariable > 0 ? parallelismByEnvironmentVariable : CPUCoresEstimation.get() - 2); ++ } + + /** + * The queue of tasks in the {@link AsyncExecutor} singleton instance. @@ -54,12 +61,16 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59 + */ + public static final AsyncExecutor instance = new AsyncExecutor(); + -+ private static volatile boolean isPaused = true; ++ private static volatile boolean isPaused = false; + private static final ReentrantLock pauseLock = new ReentrantLock(); + private static final Condition pauseCondition = pauseLock.newCondition(); + + private AsyncExecutor() { -+ super(parallelism, parallelism, 0L, TimeUnit.MILLISECONDS, queue); ++ super(parallelism, parallelism, 0L, TimeUnit.MILLISECONDS, queue, new ThreadFactoryBuilder() ++ .setNameFormat("Async Executor Thread - %1$d") ++ .setPriority(Thread.NORM_PRIORITY - 1) // Deprioritize over main ++ .setUncaughtExceptionHandler(Util::onThreadException) ++ .build()); + } + + @Override diff --git a/patches/server/0062-Remove-Paper-async-executor.patch b/patches/server/0062-Remove-Paper-async-executor.patch new file mode 100644 index 0000000..a953e18 --- /dev/null +++ b/patches/server/0062-Remove-Paper-async-executor.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MartijnMuijsers +Date: Tue, 29 Nov 2022 13:10:20 +0100 +Subject: [PATCH] Remove Paper async executor + +License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html) + +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index 1e812c4f5a8d54293084de29e8731e0b8ddcc0ae..06507695eb53067b0da9cb66e4d443f21cb6f070 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -34,6 +34,7 @@ import org.bukkit.Location; + import org.bukkit.block.BlockFace; + import org.bukkit.craftbukkit.CraftWorld; + import org.bukkit.craftbukkit.util.Waitable; ++import org.galemc.gale.concurrent.AsyncExecutor; + import org.spigotmc.AsyncCatcher; + + import javax.annotation.Nonnull; +@@ -45,6 +46,7 @@ import java.util.Queue; + import java.util.Set; + import java.util.concurrent.CompletableFuture; + import java.util.concurrent.ExecutionException; ++import java.util.concurrent.Executor; + import java.util.concurrent.LinkedBlockingQueue; + import java.util.concurrent.ThreadPoolExecutor; + import java.util.concurrent.TimeUnit; +@@ -55,14 +57,7 @@ import java.util.function.Consumer; + import java.util.function.Supplier; + + public final class MCUtil { +- public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor( +- 0, 2, 60L, TimeUnit.SECONDS, +- new LinkedBlockingQueue<>(), +- new ThreadFactoryBuilder() +- .setNameFormat("Paper Async Task Handler Thread - %1$d") +- .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) +- .build() +- ); ++ public static final Executor asyncExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper async executor + public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor( + 1, 1, 0L, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(), +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index a30024ab934b81cd76e282fab4bbf6052bdaaaaf..2534aa4fa9a023ed23b2d710fcffecd5f2fca6b9 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -148,6 +148,7 @@ import net.minecraft.world.level.storage.loot.PredicateManager; + import net.minecraft.world.phys.Vec2; + import net.minecraft.world.phys.Vec3; + import org.apache.commons.lang3.Validate; ++import org.galemc.gale.concurrent.AsyncExecutor; + import org.galemc.gale.concurrent.MinecraftServerBlockableEventLoop; + import org.galemc.gale.configuration.GaleConfigurations; + import org.galemc.gale.configuration.GaleGlobalConfiguration; +@@ -980,8 +981,10 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1); + } + // Spigot start +- io.papermc.paper.util.MCUtil.asyncExecutor.shutdown(); // Paper +- try { io.papermc.paper.util.MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper ++ // Gale start - centralized async execution - remove Paper async executor ++ AsyncExecutor.instance.shutdown(); // Paper ++ try { AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper ++ // Gale end - centralized async execution - remove Paper async executor + } catch (java.lang.InterruptedException ignored) {} // Paper + if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { + MinecraftServer.LOGGER.info("Saving usercache.json"); diff --git a/patches/server/0063-Remove-Paper-cleaner-executor.patch b/patches/server/0063-Remove-Paper-cleaner-executor.patch new file mode 100644 index 0000000..8325142 --- /dev/null +++ b/patches/server/0063-Remove-Paper-cleaner-executor.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MartijnMuijsers +Date: Tue, 29 Nov 2022 13:11:58 +0100 +Subject: [PATCH] Remove Paper cleaner executor + +License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html) + +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index 06507695eb53067b0da9cb66e4d443f21cb6f070..d9b1c85b4e36055b58c71748b005adf08c61f72f 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -58,14 +58,7 @@ import java.util.function.Supplier; + + public final class MCUtil { + public static final Executor asyncExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper async executor +- public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor( +- 1, 1, 0L, TimeUnit.SECONDS, +- new LinkedBlockingQueue<>(), +- new ThreadFactoryBuilder() +- .setNameFormat("Paper Object Cleaner") +- .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) +- .build() +- ); ++ public static final Executor cleanerExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper cleaner executor + + public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE); + diff --git a/patches/server/0064-Remove-background-executor.patch b/patches/server/0064-Remove-background-executor.patch new file mode 100644 index 0000000..e534173 --- /dev/null +++ b/patches/server/0064-Remove-background-executor.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MartijnMuijsers +Date: Tue, 29 Nov 2022 14:21:44 +0100 +Subject: [PATCH] Remove background executor + +License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html) + +diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java +index 6b7943e8348b0a41ca69fb56ccfd5f1c1484eb07..e14245a77b40fca4bacf82295ad390339aba08a9 100644 +--- a/src/main/java/net/minecraft/Util.java ++++ b/src/main/java/net/minecraft/Util.java +@@ -72,6 +72,7 @@ import net.minecraft.util.RandomSource; + import net.minecraft.util.TimeSource; + import net.minecraft.util.datafix.DataFixers; + import net.minecraft.world.level.block.state.properties.Property; ++import org.galemc.gale.concurrent.AsyncExecutor; + import org.slf4j.Logger; + + public class Util { +@@ -80,7 +81,7 @@ public class Util { + private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads"; + private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1); + private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority +- private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority ++ private static final ExecutorService BACKGROUND_EXECUTOR = AsyncExecutor.instance; // Gale - centralized async execution - remove background executor + // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread + public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() { + +@@ -219,7 +220,6 @@ public class Util { + } + + public static void shutdownExecutors() { +- shutdownExecutor(BACKGROUND_EXECUTOR); + shutdownExecutor(IO_POOL); + } + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 2534aa4fa9a023ed23b2d710fcffecd5f2fca6b9..2537f2b35e2342c97892ac347d697d72f2d2d3d0 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -981,11 +981,6 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1); + } + // Spigot start +- // Gale start - centralized async execution - remove Paper async executor +- AsyncExecutor.instance.shutdown(); // Paper +- try { AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper +- // Gale end - centralized async execution - remove Paper async executor +- } catch (java.lang.InterruptedException ignored) {} // Paper + if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { + MinecraftServer.LOGGER.info("Saving usercache.json"); + this.getProfileCache().save(false); // Paper +@@ -995,6 +990,13 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + LOGGER.info("Flushing Chunk IO"); + io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system + LOGGER.info("Closing Thread Pool"); ++ // Gale start - centralized async execution - remove Paper async executor, remove background executor ++ AsyncExecutor.instance.shutdown(); // Paper ++ try { ++ AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper ++ // Gale end - centralized async execution - remove Paper async executor ++ } catch (java.lang.InterruptedException ignored) {} // Paper ++ // Gale start - centralized async execution - remove background executor + Util.shutdownExecutors(); // Paper + LOGGER.info("Closing Server"); + try { +diff --git a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java +index de182b9473963b95085fa612f70884a56765ae43..fff4549d86e672dc7b9959ac5dd51fd04d4d62c3 100644 +--- a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java ++++ b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java +@@ -34,6 +34,7 @@ public final class AsyncExecutor extends ThreadPoolExecutor { + public static final int parallelism; + static { + int parallelismByEnvironmentVariable = Integer.getInteger("gale.threads.async", -1); ++ parallelismByEnvironmentVariable = Math.max(parallelismByEnvironmentVariable, Integer.getInteger("Paper.WorkerThreadCount", -1)); // Gale - centralized async execution - remove background executor + parallelism = Math.max(1, parallelismByEnvironmentVariable > 0 ? parallelismByEnvironmentVariable : CPUCoresEstimation.get() - 2); + } + diff --git a/patches/server/0060-Remove-bootstrap-executor.patch b/patches/server/0065-Remove-bootstrap-executor.patch similarity index 81% rename from patches/server/0060-Remove-bootstrap-executor.patch rename to patches/server/0065-Remove-bootstrap-executor.patch index 84c034c..00f1052 100644 --- a/patches/server/0060-Remove-bootstrap-executor.patch +++ b/patches/server/0065-Remove-bootstrap-executor.patch @@ -12,16 +12,16 @@ As part of: Patina (https://github.com/PatinaMC/Patina) Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index 6b7943e8348b0a41ca69fb56ccfd5f1c1484eb07..259c138f4502efa92140674fb4fb7d6256e3e228 100644 +index e14245a77b40fca4bacf82295ad390339aba08a9..d84c721ed64cf927ccc9884235b22414298ce3ed 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java -@@ -79,8 +79,8 @@ public class Util { +@@ -80,8 +80,8 @@ public class Util { private static final int DEFAULT_MAX_THREADS = 255; private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads"; private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1); - private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority - private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority -+ private static final ExecutorService BOOTSTRAP_EXECUTOR = BACKGROUND_EXECUTOR/*makeExecutor("Bootstrap", -2)*/; // Paper - add -2 priority // Gale - Patina - remove bootstrap executor + private static final ExecutorService BACKGROUND_EXECUTOR = AsyncExecutor.instance; // Gale - centralized async execution - remove background executor ++ private static final ExecutorService BOOTSTRAP_EXECUTOR = BACKGROUND_EXECUTOR; // Gale - Patina - remove bootstrap executor // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {