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:
Aikar 2020-06-02 02:19:07 -04:00
parent a4fe910f57
commit f4a47db699
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
6 changed files with 101 additions and 44 deletions

View file

@ -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;
}

View file

@ -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) {

View file

@ -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() {

View file

@ -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

View file

@ -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

View file

@ -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 {