From 64828f3a60d3efbe2e77665e0530d687a8408f56 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 29 Nov 2024 17:07:35 +0100 Subject: [PATCH] Clean up thread pool usage (#11681) Using an unbound LinkedBlockingQueue means you *have* to set core and max core thread pool size the same, as they will never go above the minimum pool size by just passing them through. So this fixes the async command executor pool to actually use 2 threads, and also cleans up other usage to be explicitly "fixed" thread pool sizes, and splits off one more in Minecraft's Util class --- patches/server/0009-MC-Utils.patch | 28 +++++----- ...er-Thread-Pool-and-Thread-Priorities.patch | 6 +-- .../0273-Async-command-map-building.patch | 19 +++---- .../server/0274-Brigadier-Mojang-API.patch | 8 +-- .../0953-Brigadier-based-command-API.patch | 10 ++-- ...y-type-tags-suggestions-in-selectors.patch | 6 +-- ...1034-Separate-dimensiondata-executor.patch | 53 +++++++++++++++++++ ...-send-Banner-patterns-to-the-client.patch} | 0 ...> 1036-Rewrite-dataconverter-system.patch} | 0 ... 1037-Moonrise-optimisation-patches.patch} | 2 +- ...data-to-disk-if-it-serializes-witho.patch} | 0 ...> 1039-API-for-checking-sent-chunks.patch} | 0 ...040-Fix-CraftWorld-isChunkGenerated.patch} | 0 ...tup-flag-to-disable-gamerule-limits.patch} | 0 ...h => 1042-Improved-Watchdog-Support.patch} | 2 +- ...-more-information-in-watchdog-dumps.patch} | 0 ...44-Entity-load-save-limit-per-chunk.patch} | 0 ...ulate-regionfile-header-if-it-is-co.patch} | 2 +- ...le-spark.patch => 1046-Bundle-spark.patch} | 2 +- ...-Improve-performance-of-mass-crafts.patch} | 0 ...Incremental-chunk-and-player-saving.patch} | 2 +- ...=> 1049-Optimise-general-POI-access.patch} | 0 ...r-desync-when-new-players-are-added.patch} | 0 ...atch => 1051-Lag-compensation-ticks.patch} | 2 +- ...n-checking-in-player-move-packet-ha.patch} | 0 ...1053-Optional-per-player-mob-spawns.patch} | 0 ...g-PreCreatureSpawnEvent-with-per-pl.patch} | 0 ...-certain-tasks-not-processing-durin.patch} | 2 +- ...llow-using-old-ender-pearl-behavior.patch} | 0 ...057-Block-Enderpearl-Travel-Exploit.patch} | 0 ...es-in-dispense-events-regarding-sta.patch} | 0 ...patch => 1059-Correct-update-cursor.patch} | 0 ...onEntityRemove-for-all-online-playe.patch} | 0 ...ove-exact-choice-recipe-ingredients.patch} | 0 ...-Eigencraft-redstone-implementation.patch} | 0 ...rformance-of-RecipeMap-removeRecipe.patch} | 0 ...in-CraftMapCanvas.drawImage-by-limi.patch} | 0 ...ate-Current-redstone-implementation.patch} | 0 ...ct-invulnerability-damage-reduction.patch} | 0 ...EntityResurrectEvent-is-uncancelled.patch} | 0 ...-to-check-if-the-server-is-sleeping.patch} | 2 +- ...API-to-allow-disallow-tick-sleeping.patch} | 2 +- ...70-Configurable-Entity-Despawn-Time.patch} | 0 ...-API.patch => 1071-Expanded-Art-API.patch} | 0 ...-ProjectileHitEvent-for-entity-hits.patch} | 0 45 files changed, 96 insertions(+), 52 deletions(-) create mode 100644 patches/server/1034-Separate-dimensiondata-executor.patch rename patches/server/{1034-Always-send-Banner-patterns-to-the-client.patch => 1035-Always-send-Banner-patterns-to-the-client.patch} (100%) rename patches/server/{1035-Rewrite-dataconverter-system.patch => 1036-Rewrite-dataconverter-system.patch} (100%) rename patches/server/{1036-Moonrise-optimisation-patches.patch => 1037-Moonrise-optimisation-patches.patch} (99%) rename patches/server/{1037-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch => 1038-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch} (100%) rename patches/server/{1038-API-for-checking-sent-chunks.patch => 1039-API-for-checking-sent-chunks.patch} (100%) rename patches/server/{1039-Fix-CraftWorld-isChunkGenerated.patch => 1040-Fix-CraftWorld-isChunkGenerated.patch} (100%) rename patches/server/{1040-Add-startup-flag-to-disable-gamerule-limits.patch => 1041-Add-startup-flag-to-disable-gamerule-limits.patch} (100%) rename patches/server/{1041-Improved-Watchdog-Support.patch => 1042-Improved-Watchdog-Support.patch} (99%) rename patches/server/{1042-Detail-more-information-in-watchdog-dumps.patch => 1043-Detail-more-information-in-watchdog-dumps.patch} (100%) rename patches/server/{1043-Entity-load-save-limit-per-chunk.patch => 1044-Entity-load-save-limit-per-chunk.patch} (100%) rename patches/server/{1044-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => 1045-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (99%) rename patches/server/{1045-Bundle-spark.patch => 1046-Bundle-spark.patch} (99%) rename patches/server/{1046-Improve-performance-of-mass-crafts.patch => 1047-Improve-performance-of-mass-crafts.patch} (100%) rename patches/server/{1047-Incremental-chunk-and-player-saving.patch => 1048-Incremental-chunk-and-player-saving.patch} (98%) rename patches/server/{1048-Optimise-general-POI-access.patch => 1049-Optimise-general-POI-access.patch} (100%) rename patches/server/{1049-Fix-entity-tracker-desync-when-new-players-are-added.patch => 1050-Fix-entity-tracker-desync-when-new-players-are-added.patch} (100%) rename patches/server/{1050-Lag-compensation-ticks.patch => 1051-Lag-compensation-ticks.patch} (98%) rename patches/server/{1051-Optimise-collision-checking-in-player-move-packet-ha.patch => 1052-Optimise-collision-checking-in-player-move-packet-ha.patch} (100%) rename patches/server/{1052-Optional-per-player-mob-spawns.patch => 1053-Optional-per-player-mob-spawns.patch} (100%) rename patches/server/{1053-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch => 1054-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch} (100%) rename patches/server/{1054-Avoid-issues-with-certain-tasks-not-processing-durin.patch => 1055-Avoid-issues-with-certain-tasks-not-processing-durin.patch} (97%) rename patches/server/{1055-Allow-using-old-ender-pearl-behavior.patch => 1056-Allow-using-old-ender-pearl-behavior.patch} (100%) rename patches/server/{1056-Block-Enderpearl-Travel-Exploit.patch => 1057-Block-Enderpearl-Travel-Exploit.patch} (100%) rename patches/server/{1057-Fix-inconsistencies-in-dispense-events-regarding-sta.patch => 1058-Fix-inconsistencies-in-dispense-events-regarding-sta.patch} (100%) rename patches/server/{1058-Correct-update-cursor.patch => 1059-Correct-update-cursor.patch} (100%) rename patches/server/{1059-Call-CraftPlayer-onEntityRemove-for-all-online-playe.patch => 1060-Call-CraftPlayer-onEntityRemove-for-all-online-playe.patch} (100%) rename patches/server/{1060-Improve-exact-choice-recipe-ingredients.patch => 1061-Improve-exact-choice-recipe-ingredients.patch} (100%) rename patches/server/{1061-Eigencraft-redstone-implementation.patch => 1062-Eigencraft-redstone-implementation.patch} (100%) rename patches/server/{1062-Improve-performance-of-RecipeMap-removeRecipe.patch => 1063-Improve-performance-of-RecipeMap-removeRecipe.patch} (100%) rename patches/server/{1063-Reduce-work-done-in-CraftMapCanvas.drawImage-by-limi.patch => 1064-Reduce-work-done-in-CraftMapCanvas.drawImage-by-limi.patch} (100%) rename patches/server/{1064-Add-Alternate-Current-redstone-implementation.patch => 1065-Add-Alternate-Current-redstone-implementation.patch} (100%) rename patches/server/{1065-Fix-incorrect-invulnerability-damage-reduction.patch => 1066-Fix-incorrect-invulnerability-damage-reduction.patch} (100%) rename patches/server/{1066-Fix-NPE-when-EntityResurrectEvent-is-uncancelled.patch => 1067-Fix-NPE-when-EntityResurrectEvent-is-uncancelled.patch} (100%) rename patches/server/{1067-API-to-check-if-the-server-is-sleeping.patch => 1068-API-to-check-if-the-server-is-sleeping.patch} (94%) rename patches/server/{1068-API-to-allow-disallow-tick-sleeping.patch => 1069-API-to-allow-disallow-tick-sleeping.patch} (97%) rename patches/server/{1069-Configurable-Entity-Despawn-Time.patch => 1070-Configurable-Entity-Despawn-Time.patch} (100%) rename patches/server/{1070-Expanded-Art-API.patch => 1071-Expanded-Art-API.patch} (100%) rename patches/server/{1071-Call-ProjectileHitEvent-for-entity-hits.patch => 1072-Call-ProjectileHitEvent-for-entity-hits.patch} (100%) diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 2bea8ec9a7..98b049b563 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -4844,10 +4844,10 @@ index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65 +} diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41cea31c4d +index 0000000000000000000000000000000000000000..a4ac34ebb58a404f4fca7e763e61d4ab05ee3af4 --- /dev/null +++ b/src/main/java/io/papermc/paper/util/MCUtil.java -@@ -0,0 +1,209 @@ +@@ -0,0 +1,205 @@ +package io.papermc.paper.util; + +import com.google.common.collect.Collections2; @@ -4861,9 +4861,8 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41 +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; -+import java.util.concurrent.LinkedBlockingQueue; -+import java.util.concurrent.ThreadPoolExecutor; -+import java.util.concurrent.TimeUnit; ++import java.util.concurrent.ExecutorService; ++import java.util.concurrent.Executors; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; @@ -4888,13 +4887,10 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41 + run.run(); + } + }; -+ public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor( -+ 2, 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 ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() ++ .setNameFormat("Paper Async Task Handler Thread - %1$d") ++ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) ++ .build() + ); + + private MCUtil() { @@ -5029,7 +5025,7 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41 + } + + public static void scheduleAsyncTask(Runnable run) { -+ asyncExecutor.execute(run); ++ ASYNC_EXECUTOR.execute(run); + } + + public static ResourceKey toResourceKey( @@ -5216,15 +5212,15 @@ index 3e5a85a7ad6149b04622c254fbc2e174896a4128..3f662692ed4846e026a9d48595e7b3b2 + } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8e16bc7da15824723f1d7d4bff87fac181978500..709330ca9caa82a6de71767b3d5c32f97ea1d68b 100644 +index 8e16bc7da15824723f1d7d4bff87fac181978500..1b6cf839450cc69bd3cda6d874656c5345b0ac51 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -988,6 +988,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement(); -+ executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier)); ++ executorService = Executors.newFixedThreadPool(i, target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier)); + } + /* final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement(); ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) { @@ -94,7 +94,7 @@ index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46 return new TracingExecutor(executorService); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c4d8918a7accbe5eb3035b4ec3b423f30c613d60..b54c1ecf3384fba741fa6334caee498b83887508 100644 +index af20a16e18673a629fc3033d8e7e07eba855b1c7..2a4f8075867a302afd98bdf9ac8b11622c29082d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -332,6 +332,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ this.sendAsync(player); -+ }); ++ COMMAND_SENDING_POOL.execute(() -> this.sendAsync(player)); + } + -+ public static final java.util.concurrent.ThreadPoolExecutor COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor( -+ 0, 2, 60L, java.util.concurrent.TimeUnit.SECONDS, -+ new java.util.concurrent.LinkedBlockingQueue<>(), ++ public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = java.util.concurrent.Executors.newFixedThreadPool(2, + new com.google.common.util.concurrent.ThreadFactoryBuilder() + .setNameFormat("Paper Async Command Builder Thread Pool - %1$d") + .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)) -+ .build(), -+ new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy() ++ .build() + ); + + private void sendAsync(ServerPlayer player) { @@ -37,7 +32,7 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee9860 Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); -@@ -472,7 +490,14 @@ public class Commands { +@@ -472,7 +485,14 @@ public class Commands { for (CommandNode node : rootcommandnode.getChildren()) { bukkit.add(node.getName()); } @@ -53,7 +48,7 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee9860 event.getPlayer().getServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 13aa191235ac6bb1d00d89ae29c750595cc6be78..0f1a7b649d398a875b57746530242e3ced595bfd 100644 +index 9a9291282f7ec99be9badf8b32fab5f0ea0f1037..feb45369b41b597fd603c12f3da23759923b6a6d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -944,6 +944,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { runSync(player, bukkit, rootcommandnode); }); -@@ -498,6 +499,7 @@ public class Commands { +@@ -493,6 +494,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { // Paper end - Perf: Async command map building @@ -106,7 +106,7 @@ index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d3 PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -516,6 +518,11 @@ public class Commands { +@@ -511,6 +513,11 @@ public class Commands { while (iterator.hasNext()) { CommandNode commandnode2 = (CommandNode) iterator.next(); diff --git a/patches/server/0953-Brigadier-based-command-API.patch b/patches/server/0953-Brigadier-based-command-API.patch index 5296fff1c9..0f4bec1390 100644 --- a/patches/server/0953-Brigadier-based-command-API.patch +++ b/patches/server/0953-Brigadier-based-command-API.patch @@ -2068,7 +2068,7 @@ index fc0c60b22844ed010aede2fa125b9fa440d3de80..3549ffea451b932602efb113844ba21a public org.bukkit.command.CommandSender getBukkitSender() { return this.source.getBukkitSender(this); diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187feb694761 100644 +index 26bc8d7075f8a9c411776ab91aeddcd776d21348..2fc5651d1546fd4bb10b0617540e906f483cb36c 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -159,7 +159,7 @@ public class Commands { @@ -2135,7 +2135,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f StackTraceElement[] astacktraceelement = exception.getStackTrace(); for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) { -@@ -478,13 +497,7 @@ public class Commands { +@@ -473,13 +492,7 @@ public class Commands { private void sendAsync(ServerPlayer player) { // Paper end - Perf: Async command map building Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues @@ -2150,7 +2150,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f RootCommandNode rootcommandnode = new RootCommandNode(); map.put(this.dispatcher.getRoot(), rootcommandnode); -@@ -518,6 +531,7 @@ public class Commands { +@@ -513,6 +526,7 @@ public class Commands { } private void fillUsableCommands(CommandNode tree, CommandNode result, CommandSourceStack source, Map, CommandNode> resultNodes) { @@ -2158,7 +2158,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f Iterator iterator = tree.getChildren().iterator(); while (iterator.hasNext()) { -@@ -531,6 +545,42 @@ public class Commands { +@@ -526,6 +540,42 @@ public class Commands { if (commandnode2.canUse(source)) { ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error @@ -2218,7 +2218,7 @@ index 55484826fc5ddd04ae024e25a0251796d7fa9c28..237e4f7b24908e9ade9a483eb7ae05fa Component component = message.resolveComponent(commandSourceStack); CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 95786d2e1a8ac0fdbe8d449b3f100ac0512ee21e..b13b3991292ab96542ba390f3e8e3ff0d7529c44 100644 +index 9c1e1c049db55e73851e3d513cba25027bd0c3b4..ab1a2c4272c4c84743ff501bb35816d35c9d4c94 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -316,7 +316,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below Iterator iterator = tree.getChildren().iterator(); @@ -48,7 +48,7 @@ index b1571c162fd8ab7239a7f4aafea5187feb694761..1e7b99a82184f73aa31cb2e0d4e52a80 while (iterator.hasNext()) { CommandNode commandnode2 = (CommandNode) iterator.next(); // Paper start - Brigadier API -@@ -596,6 +597,12 @@ public class Commands { +@@ -591,6 +592,12 @@ public class Commands { if (requiredargumentbuilder.getSuggestionsProvider() != null) { requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider())); diff --git a/patches/server/1034-Separate-dimensiondata-executor.patch b/patches/server/1034-Separate-dimensiondata-executor.patch new file mode 100644 index 0000000000..40c89f1045 --- /dev/null +++ b/patches/server/1034-Separate-dimensiondata-executor.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Nassim Jahnke +Date: Thu, 28 Nov 2024 10:35:58 +0100 +Subject: [PATCH] Separate dimensiondata executor + + +diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java +index 276ad77ecb274b6cd454d0f92457964a8eaa5824..1360aa8202542d3d0f32247f1123575fc2c38ff1 100644 +--- a/src/main/java/net/minecraft/Util.java ++++ b/src/main/java/net/minecraft/Util.java +@@ -94,6 +94,7 @@ public class Util { + private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads"; + private static final TracingExecutor BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - Perf: add priority + private static final TracingExecutor IO_POOL = makeIoExecutor("IO-Worker-", false); ++ public static final TracingExecutor DIMENSION_DATA_IO_POOL = makeExtraIoExecutor("Dimension-Data-IO-Worker-"); // Paper - Separate dimension data IO pool + private static final TracingExecutor DOWNLOAD_POOL = makeIoExecutor("Download-", true); + // 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() { +@@ -260,6 +261,21 @@ public class Util { + })); + } + ++ // Paper start - Separate dimension data IO pool ++ private static TracingExecutor makeExtraIoExecutor(String namePrefix) { ++ AtomicInteger atomicInteger = new AtomicInteger(1); ++ return new TracingExecutor(Executors.newFixedThreadPool(4, runnable -> { ++ Thread thread = new Thread(runnable); ++ String string2 = namePrefix + atomicInteger.getAndIncrement(); ++ TracyClient.setThreadName(string2, namePrefix.hashCode()); ++ thread.setName(string2); ++ thread.setDaemon(false); ++ thread.setUncaughtExceptionHandler(Util::onThreadException); ++ return thread; ++ })); ++ } ++ // Paper end - Separate dimension data IO pool ++ + public static void throwAsRuntime(Throwable t) { + throw t instanceof RuntimeException ? (RuntimeException)t : new RuntimeException(t); + } +diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +index d16f124e0371ce943298c8d7d9bfac21e98cf885..8212f2dfba5c2eee5a823b5217fb43dc870d228a 100644 +--- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java ++++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +@@ -155,7 +155,7 @@ public class DimensionDataStorage implements AutoCloseable { + } catch (IOException var3) { + LOGGER.error("Could not save data to {}", path.getFileName(), var3); + } +- }, Util.ioPool()); ++ }, Util.DIMENSION_DATA_IO_POOL); // Paper - Separate dimension data IO pool + } + + public void saveAndJoin() { diff --git a/patches/server/1034-Always-send-Banner-patterns-to-the-client.patch b/patches/server/1035-Always-send-Banner-patterns-to-the-client.patch similarity index 100% rename from patches/server/1034-Always-send-Banner-patterns-to-the-client.patch rename to patches/server/1035-Always-send-Banner-patterns-to-the-client.patch diff --git a/patches/server/1035-Rewrite-dataconverter-system.patch b/patches/server/1036-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/1035-Rewrite-dataconverter-system.patch rename to patches/server/1036-Rewrite-dataconverter-system.patch diff --git a/patches/server/1036-Moonrise-optimisation-patches.patch b/patches/server/1037-Moonrise-optimisation-patches.patch similarity index 99% rename from patches/server/1036-Moonrise-optimisation-patches.patch rename to patches/server/1037-Moonrise-optimisation-patches.patch index ae38b2a8aa..b2bbfd3c7a 100644 --- a/patches/server/1036-Moonrise-optimisation-patches.patch +++ b/patches/server/1037-Moonrise-optimisation-patches.patch @@ -23410,7 +23410,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index e18692ad6bdbc8bc2df605833501b1ad888b8b7d..ed1f8c735bf9f13014112056b85ff195b02ee76e 100644 +index 57b242a4a1de49e8869e8ec83e74d60d877a4003..9cb435573d0b1bdf5488bd5b9cef5d2aba6a1c2d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -204,7 +204,7 @@ import org.bukkit.event.server.ServerLoadEvent; diff --git a/patches/server/1037-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/1038-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/server/1037-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/server/1038-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/server/1038-API-for-checking-sent-chunks.patch b/patches/server/1039-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/server/1038-API-for-checking-sent-chunks.patch rename to patches/server/1039-API-for-checking-sent-chunks.patch diff --git a/patches/server/1039-Fix-CraftWorld-isChunkGenerated.patch b/patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch similarity index 100% rename from patches/server/1039-Fix-CraftWorld-isChunkGenerated.patch rename to patches/server/1040-Fix-CraftWorld-isChunkGenerated.patch diff --git a/patches/server/1040-Add-startup-flag-to-disable-gamerule-limits.patch b/patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch similarity index 100% rename from patches/server/1040-Add-startup-flag-to-disable-gamerule-limits.patch rename to patches/server/1041-Add-startup-flag-to-disable-gamerule-limits.patch diff --git a/patches/server/1041-Improved-Watchdog-Support.patch b/patches/server/1042-Improved-Watchdog-Support.patch similarity index 99% rename from patches/server/1041-Improved-Watchdog-Support.patch rename to patches/server/1042-Improved-Watchdog-Support.patch index d6ad1f105d..d9040f3b39 100644 --- a/patches/server/1041-Improved-Watchdog-Support.patch +++ b/patches/server/1042-Improved-Watchdog-Support.patch @@ -117,7 +117,7 @@ index e114e687f2f4503546687fd6792226a643af8793..90ca25c4aaf92a5639839a7cdaee2ffc /* CraftBukkit start - Replace everything OptionParser optionparser = new OptionParser(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ed1f8c735bf9f13014112056b85ff195b02ee76e..b29dbab3c26c078eb993183d808149d958857f3a 100644 +index 9cb435573d0b1bdf5488bd5b9cef5d2aba6a1c2d..4ac8bc8dc326ef12c4ffdfdf8325f3111ca5b665 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -317,7 +317,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop