diff --git a/divinemc-server/minecraft-patches/features/0036-Virtual-Threads.patch b/divinemc-server/minecraft-patches/features/0036-Virtual-Threads.patch new file mode 100644 index 0000000..50d26e0 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0036-Virtual-Threads.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Mon, 24 Feb 2025 19:29:58 +0300 +Subject: [PATCH] Virtual Threads + + +diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java +index d7922847bd398d809e8b8a31bf136c804305a32b..559fd3d12dc5bc84bd976e684153295d8fb7cf64 100644 +--- a/net/minecraft/commands/Commands.java ++++ b/net/minecraft/commands/Commands.java +@@ -480,7 +480,7 @@ public class Commands { + } + + // Fixed pool, but with discard policy +- public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor( ++ public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualCommandBuilderScheduler ? java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor() : new java.util.concurrent.ThreadPoolExecutor( // DivineMC - Virtual Threads + 2, 2, 0, java.util.concurrent.TimeUnit.MILLISECONDS, + new java.util.concurrent.LinkedBlockingQueue<>(), + new com.google.common.util.concurrent.ThreadFactoryBuilder() +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index 85f81c83aff81133289a03f12a059729b7d2e00e..3f286034d50b53fbd71b4f64d83dc78b46f57f1d 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -2814,8 +2814,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop +Date: Mon, 24 Feb 2025 19:36:33 +0300 +Subject: [PATCH] Virtual Threads + + +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index a4ac34ebb58a404f4fca7e763e61d4ab05ee3af4..3c7f66571ca346e9776ba6044bbb0f0263f34157 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -37,7 +37,7 @@ public final class MCUtil { + run.run(); + } + }; +- public static final ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() ++ public static final ExecutorService ASYNC_EXECUTOR = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualAsyncExecutor ? Executors.newVirtualThreadPerTaskExecutor() : Executors.newFixedThreadPool(2, new ThreadFactoryBuilder() // DivineMC - Virtual Threads + .setNameFormat("Paper Async Task Handler Thread - %1$d") + .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER)) + .build() +diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java +index 0ca279fb71d39c81b1f608e0ee9ba3e498d55fa3..bfa84901c5e0e50ab3f713293035aefbcf4488e6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java ++++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java +@@ -31,14 +31,18 @@ import java.util.ArrayList; + import java.util.Iterator; + import java.util.List; + import java.util.concurrent.Executor; ++import java.util.concurrent.ExecutorService; + import java.util.concurrent.Executors; + import java.util.concurrent.SynchronousQueue; + import java.util.concurrent.ThreadPoolExecutor; + import java.util.concurrent.TimeUnit; + + public class CraftAsyncScheduler extends CraftScheduler { +- +- private final ThreadPoolExecutor executor = new ThreadPoolExecutor( ++ // DivineMC start - Virtual Threads ++ private final ExecutorService executor = org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && org.bxteam.divinemc.DivineConfig.virtualBukkitScheduler ++ ? Executors.newVirtualThreadPerTaskExecutor() ++ : new ThreadPoolExecutor( ++ // DivineMC end - Virtual Threads + 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(), + new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); + private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() +@@ -47,8 +51,12 @@ public class CraftAsyncScheduler extends CraftScheduler { + + CraftAsyncScheduler() { + super(true); +- executor.allowCoreThreadTimeOut(true); +- executor.prestartAllCoreThreads(); ++ // DivineMC start - Virtual Threads ++ if (!org.bxteam.divinemc.DivineConfig.virtualThreadsEnabled && !org.bxteam.divinemc.DivineConfig.virtualBukkitScheduler) { ++ ((ThreadPoolExecutor) executor).allowCoreThreadTimeOut(true); ++ ((ThreadPoolExecutor) executor).prestartAllCoreThreads(); ++ } ++ // DivineMC end - Virtual Threads + } + + @Override diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java index 552db68..510efba 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java @@ -314,6 +314,31 @@ public class DivineConfig { "Message to send to the client when they are disconnected for not having No Chat Reports"); } + public static boolean virtualThreadsEnabled = false; + public static boolean virtualBukkitScheduler = false; + public static boolean virtualChatScheduler = false; + public static boolean virtualAuthenticatorScheduler = false; + public static boolean virtualTabCompleteScheduler = false; + public static boolean virtualAsyncExecutor = false; + public static boolean virtualCommandBuilderScheduler = false; + private static void virtualThreads() { + virtualThreadsEnabled = getBoolean("settings.virtual-threads.enabled", virtualThreadsEnabled, + "Enables use of virtual threads that was added in Java 21"); + + virtualBukkitScheduler = getBoolean("settings.virtual-threads.bukkit-scheduler", virtualBukkitScheduler, + "Uses virtual threads for the Bukkit scheduler."); + virtualChatScheduler = getBoolean("settings.virtual-threads.chat-scheduler", virtualChatScheduler, + "Uses virtual threads for the Chat scheduler."); + virtualAuthenticatorScheduler = getBoolean("settings.virtual-threads.authenticator-scheduler", virtualAuthenticatorScheduler, + "Uses virtual threads for the Authenticator scheduler."); + virtualTabCompleteScheduler = getBoolean("settings.virtual-threads.tab-complete-scheduler", virtualTabCompleteScheduler, + "Uses virtual threads for the Tab Complete scheduler."); + virtualAsyncExecutor = getBoolean("settings.virtual-threads.async-executor", virtualAsyncExecutor, + "Uses virtual threads for the MCUtil async executor."); + virtualCommandBuilderScheduler = getBoolean("settings.virtual-threads.command-builder-scheduler", virtualCommandBuilderScheduler, + "Uses virtual threads for the Async Command Builder Thread Pool."); + } + public static boolean asyncPathfinding = true; public static int asyncPathfindingMaxThreads = 2; public static int asyncPathfindingKeepalive = 60;