112 lines
5.1 KiB
Diff
112 lines
5.1 KiB
Diff
From 49fd7e234581b6c8da9707da2854313aae503874 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Mon, 1 Jan 2018 16:10:24 -0500
|
|
Subject: [PATCH] Configurable Max Chunk Gens per Tick
|
|
|
|
Limit the number of generations that can occur in a single tick, forcing them
|
|
to be spread out more.
|
|
|
|
Defaulting to 10 as an average generation is going to be 3-6ms, which means 10 will
|
|
likely cause the server to lose TPS, but constrain how much.
|
|
|
|
This should result in no noticeable speed reduction in generation for servers not
|
|
lagging, and let larger servers reduce this value according to their own desires.
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 703642c0b..faa7597b3 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -376,4 +376,15 @@ public class PaperWorldConfig {
|
|
}
|
|
log("Max Chunk Sends Per Tick: " + maxChunkSendsPerTick);
|
|
}
|
|
+
|
|
+ public int maxChunkGensPerTick = 10;
|
|
+ private void maxChunkGensPerTick() {
|
|
+ maxChunkGensPerTick = getInt("max-chunk-gens-per-tick", maxChunkGensPerTick);
|
|
+ if (maxChunkGensPerTick <= 0) {
|
|
+ maxChunkGensPerTick = Integer.MAX_VALUE;
|
|
+ log("Max Chunk Gens Per Tick: Unlimited (NOT RECOMMENDED)");
|
|
+ } else {
|
|
+ log("Max Chunk Gens Per Tick: " + maxChunkGensPerTick);
|
|
+ }
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
|
index 344b95233..fcd9f5491 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
|
@@ -28,6 +28,7 @@ public class PlayerChunk {
|
|
// CraftBukkit start - add fields
|
|
// You know the drill, https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse
|
|
// All may seem good at first, but there's deeper issues if you play for a bit
|
|
+ boolean chunkExists; // Paper
|
|
private boolean loadInProgress = false;
|
|
private Runnable loadedRunnable = new Runnable() {
|
|
public void run() {
|
|
@@ -49,6 +50,7 @@ public class PlayerChunk {
|
|
this.playerChunkMap = playerchunkmap;
|
|
this.location = new ChunkCoordIntPair(i, j);
|
|
this.chunk = playerchunkmap.getWorld().getChunkProviderServer().getOrLoadChunkAt(i, j);
|
|
+ this.chunkExists = this.chunk != null || ChunkIOExecutor.hasQueuedChunkLoad(playerChunkMap.getWorld(), i, j); // Paper
|
|
markChunkUsed(); // Paper - delay chunk unloads
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
index 9fd07f859..e29aaab2d 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -140,6 +140,7 @@ public class PlayerChunkMap {
|
|
// Spigot start
|
|
org.spigotmc.SlackActivityAccountant activityAccountant = this.world.getMinecraftServer().slackActivityAccountant;
|
|
activityAccountant.startActivity(0.5);
|
|
+ int chunkGensAllowed = world.paperConfig.maxChunkGensPerTick; // Paper
|
|
// Spigot end
|
|
|
|
Iterator iterator1 = this.h.iterator();
|
|
@@ -149,6 +150,11 @@ public class PlayerChunkMap {
|
|
|
|
if (playerchunk1.f() == null) {
|
|
boolean flag = playerchunk1.a(PlayerChunkMap.b);
|
|
+ // Paper start
|
|
+ if (flag && !playerchunk1.chunkExists && chunkGensAllowed-- <= 0) {
|
|
+ continue;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
if (playerchunk1.a(flag)) {
|
|
iterator1.remove();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
|
index 9aaca21a7..f50d55c8e 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java
|
|
@@ -35,4 +35,10 @@ public class ChunkIOExecutor {
|
|
public static void tick() {
|
|
instance.finishActive();
|
|
}
|
|
+
|
|
+ // Paper start
|
|
+ public static boolean hasQueuedChunkLoad(World world, int x, int z) {
|
|
+ return instance.hasTask(new QueuedChunk(x, z, null, world, null));
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java b/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java
|
|
index 193c3621c..cf1258c55 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java
|
|
@@ -351,4 +351,10 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> {
|
|
public void setActiveThreads(final int coreSize) {
|
|
pool.setCorePoolSize(coreSize);
|
|
}
|
|
+
|
|
+ // Paper start
|
|
+ public boolean hasTask(P parameter) throws IllegalStateException {
|
|
+ return tasks.get(parameter) != null;
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
--
|
|
2.18.0
|
|
|