mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 15:30:19 +01:00
Improve Thread Pool usage to allow single threads for single cpu servers
Switch to a standard fixed size ThreadPoolExecutor as we don't use the advanced capabilities of a ForkJoinPool. ForkJoinPool does not allow single threads, and really rather not use 2 different executor types based on core count. Also, change thread priorities so that main thread is prioritized by the OS at a higher priority than the other threads. May not help too much but it at least signals the OS the information to know main is more important.
This commit is contained in:
parent
a4fe910f57
commit
f4a47db699
6 changed files with 101 additions and 44 deletions
|
@ -0,0 +1,90 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 23 Oct 2018 23:14:38 -0400
|
||||
Subject: [PATCH] Improve Server Thread Pool and Thread Priorities
|
||||
|
||||
Use a simple executor since Fork join is a much more complex pool
|
||||
type and we are not using its capabilities.
|
||||
|
||||
Set thread priorities so main thread has above normal priority over
|
||||
server threads
|
||||
|
||||
Allow usage of a single thread executor by not using ForkJoin so single core CPU's.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index bbda856c148588402731c03cd166acd2e1f4eee3..5d54825171d5214d504b3fad03342c0769ff50f9 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1361,6 +1361,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
dedicatedserver.setEraseCache(true);
|
||||
}
|
||||
|
||||
+ dedicatedserver.serverThread.setPriority(Thread.NORM_PRIORITY+2); // Paper - boost priority
|
||||
dedicatedserver.serverThread.start();
|
||||
// CraftBukkit end
|
||||
} catch (Exception exception) {
|
||||
diff --git a/src/main/java/net/minecraft/server/ServerWorkerThread.java b/src/main/java/net/minecraft/server/ServerWorkerThread.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..59cfb76d737f923c7e424743ef370c969ae14c26
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/net/minecraft/server/ServerWorkerThread.java
|
||||
@@ -0,0 +1,24 @@
|
||||
+package net.minecraft.server;
|
||||
+
|
||||
+import java.util.concurrent.CompletionException;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+
|
||||
+public class ServerWorkerThread extends Thread {
|
||||
+ private static final AtomicInteger threadId = new AtomicInteger(1);
|
||||
+ public ServerWorkerThread(Runnable target) {
|
||||
+ super(target, "Server-Worker-" + threadId.getAndIncrement());
|
||||
+ setPriority(Thread.NORM_PRIORITY-1); // Deprioritize over main
|
||||
+ this.setUncaughtExceptionHandler((thread, throwable) -> {
|
||||
+ if (throwable instanceof CompletionException) {
|
||||
+ throwable = throwable.getCause();
|
||||
+ }
|
||||
+
|
||||
+ if (throwable instanceof ReportedException) {
|
||||
+ DispenserRegistry.a(((ReportedException) throwable).a().e());
|
||||
+ System.exit(-1);
|
||||
+ }
|
||||
+
|
||||
+ MinecraftServer.LOGGER.error(String.format("Caught exception in thread %s", thread), throwable);
|
||||
+ });
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
index 7e224ebeff3bf34270df173a47b08d3290c00670..20d803ad68ea65fd725d6eb3317b998c1692a7b3 100644
|
||||
--- a/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
+++ b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
@@ -66,14 +66,17 @@ public class SystemUtils {
|
||||
}
|
||||
|
||||
private static ExecutorService k() {
|
||||
- int i = MathHelper.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, 7);
|
||||
- Object object;
|
||||
+ // Paper start - use simpler thread pool that allows 1 thread
|
||||
+ int i = Math.min(8, Math.max(Runtime.getRuntime().availableProcessors() - 2, 1));
|
||||
+ i = Integer.getInteger("Paper.WorkerThreadCount", i);
|
||||
+ ExecutorService object;
|
||||
|
||||
if (i <= 0) {
|
||||
object = MoreExecutors.newDirectExecutorService();
|
||||
} else {
|
||||
- object = new ForkJoinPool(i, (forkjoinpool) -> {
|
||||
- ForkJoinWorkerThread forkjoinworkerthread = new ForkJoinWorkerThread(forkjoinpool) {
|
||||
+ object = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<Runnable>(), ServerWorkerThread::new);
|
||||
+ }
|
||||
+ /*
|
||||
protected void onTermination(Throwable throwable) {
|
||||
if (throwable != null) {
|
||||
SystemUtils.LOGGER.warn("{} died", this.getName(), throwable);
|
||||
@@ -100,7 +103,7 @@ public class SystemUtils {
|
||||
|
||||
SystemUtils.LOGGER.error(String.format("Caught exception in thread %s", thread), throwable);
|
||||
}, true);
|
||||
- }
|
||||
+ }*/ // Paper end
|
||||
|
||||
return (ExecutorService) object;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 23 Oct 2018 23:14:38 -0400
|
||||
Subject: [PATCH] Use more reasonable thread count default for bootstrap
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
index 7e224ebeff3bf34270df173a47b08d3290c00670..0b6b7d2b84aa595a80aae1c580d8794528910bbc 100644
|
||||
--- a/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
+++ b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
@@ -66,7 +66,8 @@ public class SystemUtils {
|
||||
}
|
||||
|
||||
private static ExecutorService k() {
|
||||
- int i = MathHelper.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, 7);
|
||||
+ int i = Math.min(8, Math.max(Runtime.getRuntime().availableProcessors() - 2, 2)); // Paper - use more reasonable default - 2 is hard minimum to avoid using unlimited threads
|
||||
+ i = Integer.getInteger("Paper.WorkerThreadCount", i); // Paper - allow overriding
|
||||
Object object;
|
||||
|
||||
if (i <= 0) {
|
|
@ -16,10 +16,10 @@ handling that should have been handled synchronously will be handled
|
|||
synchronously when the server gets shut down.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index ae4d62d52c0763849d06709fc405018711db6f90..4b50158fe12533d0af541be343731d220e772bd9 100644
|
||||
index 992c03d799f9dbbb9f63559d787124b04b00283e..eabca3975af61b669fd31a23cb7c27883db7833e 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2220,7 +2220,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
@@ -2221,7 +2221,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public boolean isMainThread() {
|
||||
|
|
|
@ -2949,7 +2949,7 @@ index 20f54baacebe98435539d4cbef41f182040db2e9..9f8c0e10e42d233a8b74ee5a71fb8fb6
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index cfed5f51431ec5aecb538a321327bfb6e8a0bd88..aadc4635ecef4e5ba19ff56c37ecbdc5a1721ec6 100644
|
||||
index 7920d24ab089fb8360ef74946cf7dc35cb7625eb..7956b082351e5923073a97d88009e9e288c13c11 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -780,6 +780,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
|
@ -3519,7 +3519,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..6552bbf06637b08626cbf0fb352123c3
|
|||
return this.m;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
index 96d26b45851c4066978186d49eed7ee131cc9140..c626134752f685d6357f2ee4d4e9f64eb0dbb8bf 100644
|
||||
index a5700a955b6d7927228a14128860b49e79e61f03..6a7bdf8c5f38ca4eb578e1104375e5773269330c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
@@ -541,6 +541,13 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
|
@ -3830,19 +3830,6 @@ index db9f0196bda4c987de6cf63eea437b7154d47b57..a6d8ef5eb44f3f851a3a1be4032ca21a
|
|||
}
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
index 0b6b7d2b84aa595a80aae1c580d8794528910bbc..575470592ec6c6adc4f2d9cc4d05da3ccfd869df 100644
|
||||
--- a/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
+++ b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
@@ -70,7 +70,7 @@ public class SystemUtils {
|
||||
i = Integer.getInteger("Paper.WorkerThreadCount", i); // Paper - allow overriding
|
||||
Object object;
|
||||
|
||||
- if (i <= 0) {
|
||||
+ if (i <= 0 || (Runtime.getRuntime().availableProcessors() == 1 && !Boolean.getBoolean("Paper.allowAsyncChunksSingleCore"))) { // Paper - disable server worker queue if single core system
|
||||
object = MoreExecutors.newDirectExecutorService();
|
||||
} else {
|
||||
object = new ForkJoinPool(i, (forkjoinpool) -> {
|
||||
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
|
||||
index 75ab9f185b3231113dfa387c956a707b403bb2db..8055f5998213ab1c6c10d03d88d2b14d220a5e40 100644
|
||||
--- a/src/main/java/net/minecraft/server/TicketType.java
|
||||
|
|
|
@ -87,7 +87,7 @@ index f8f225e18fa38cad917f52a379233e0a7a869b07..3ee7e5671dd2519cec72b81211f1f391
|
|||
version = getInt("config-version", 20);
|
||||
set("config-version", 20);
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index f9694d188cc61f123fca4d54bf14fb7466b06a6c..b701db638370c0d07d5be0f61c6cbf19168cde8e 100644
|
||||
index fce55573507214ab6a10381721dd2bf7acb24d5b..711a00c9e3781d3b32f2b514302f530df15a4257 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -106,6 +106,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
|
@ -115,7 +115,7 @@ index f9694d188cc61f123fca4d54bf14fb7466b06a6c..b701db638370c0d07d5be0f61c6cbf19
|
|||
this.circularTimer.a(i1 - i);
|
||||
this.methodProfiler.exit();
|
||||
org.spigotmc.WatchdogThread.tick(); // Spigot
|
||||
@@ -2275,4 +2286,30 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
@@ -2276,4 +2287,30 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
return SERVER; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
|
|
@ -101,7 +101,7 @@ index cfe43e882e524b6ab3d9702e81269c97e6b75eba..2632c7c3ec77918be7979f2aa49209e5
|
|||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index b701db638370c0d07d5be0f61c6cbf19168cde8e..4ea3468614df36e1c148a44bb15d2201da281df3 100644
|
||||
index 711a00c9e3781d3b32f2b514302f530df15a4257..1bdf16bd8298ccbfa9ea2604ac61ee15bee96e20 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -144,6 +144,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
|
@ -237,7 +237,7 @@ index ea6b310e8e4741c8bb301e5bc586faca8bea5e06..6bdaaf8daef15cd7c11943254e412e0e
|
|||
list.stream().map((playerchunk) -> {
|
||||
CompletableFuture completablefuture;
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
index ab2831830ad3a4cec0671d189e0534c843b47f5e..78040e83899f1ef1a6d5c456beb9d13959307c18 100644
|
||||
index 611dea90200fe346915d66317e21d94154381e97..5428f306340acb92b93fe133b827173b646e5d4c 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
||||
@@ -400,7 +400,7 @@ public abstract class PlayerList {
|
||||
|
@ -250,10 +250,10 @@ index ab2831830ad3a4cec0671d189e0534c843b47f5e..78040e83899f1ef1a6d5c456beb9d139
|
|||
|
||||
// Paper start - Remove from collideRule team if needed
|
||||
diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
index 575470592ec6c6adc4f2d9cc4d05da3ccfd869df..7efe0224632c2605da49e415847c7b1c915308f0 100644
|
||||
index 20d803ad68ea65fd725d6eb3317b998c1692a7b3..aa399e7f6518ff70f2214161319170b1fc911751 100644
|
||||
--- a/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
+++ b/src/main/java/net/minecraft/server/SystemUtils.java
|
||||
@@ -110,6 +110,7 @@ public class SystemUtils {
|
||||
@@ -112,6 +112,7 @@ public class SystemUtils {
|
||||
return SystemUtils.c;
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ index 575470592ec6c6adc4f2d9cc4d05da3ccfd869df..7efe0224632c2605da49e415847c7b1c
|
|||
SystemUtils.c.shutdown();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index ac8b21e69b198612427a81a16fc1a3ff0b0cb558..42be4edb36200626913fa99b1e67956933022531 100644
|
||||
index 6f7da0a79bbbb2be354796033baa498845aaea7c..8cf191ec7f7c825e3d0996b7e224956a569ab2ba 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -793,6 +793,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
|
|
Loading…
Reference in a new issue