aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAikar <[email protected]>2020-07-27 22:40:54 -0400
committerAikar <[email protected]>2020-07-27 22:40:54 -0400
commit5657364b458ddc78cedd404eb78b7c2b638fdde7 (patch)
treee918a8cf84a64bbddecfe0f17c29cec02d7524a8
parent01337462914c1d203b4a2df5d8f9549304f38b19 (diff)
downloadPaper-5657364b458ddc78cedd404eb78b7c2b638fdde7.tar.gz
Paper-5657364b458ddc78cedd404eb78b7c2b638fdde7.zip
Fix Light Prioritization Issues
Ensures light priorities are properly processed before processing new work, skipping the threads queue. also stops processing work on task submission. Also drops dead chunks light work to not waste time on work thats going to be discarded.
-rw-r--r--Spigot-Server-Patches/0536-Optimize-Light-Engine.patch85
1 files changed, 59 insertions, 26 deletions
diff --git a/Spigot-Server-Patches/0536-Optimize-Light-Engine.patch b/Spigot-Server-Patches/0536-Optimize-Light-Engine.patch
index 56f8be81f9..d93ce41502 100644
--- a/Spigot-Server-Patches/0536-Optimize-Light-Engine.patch
+++ b/Spigot-Server-Patches/0536-Optimize-Light-Engine.patch
@@ -1095,21 +1095,21 @@ index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..f744f62c93370d096c113f92ee81a823
lightenginelayer.a(Long.MAX_VALUE, l3, 15, false);
}
diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java
-index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d7de86509 100644
+index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..23352a82852404a294c882ed51b917b968b90902 100644
--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java
+++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java
-@@ -14,8 +14,98 @@ import org.apache.logging.log4j.Logger;
- public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+@@ -15,15 +15,119 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private static final Logger LOGGER = LogManager.getLogger();
-- private final ThreadedMailbox<Runnable> b;
+ private final ThreadedMailbox<Runnable> b;
- private final ObjectList<Pair<LightEngineThreaded.Update, Runnable>> c = new ObjectArrayList();
-+ private final ThreadedMailbox<Runnable> b; ThreadedMailbox<Runnable> mailbox; // Paper
+- private final PlayerChunkMap d;
+ // Paper start
+ private static final int MAX_PRIORITIES = PlayerChunkMap.GOLDEN_TICKET + 2;
++ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> priorityChanges = new java.util.concurrent.ConcurrentLinkedQueue<>();
+
+ public void changePriority(long pair, int currentPriority, int priority) {
-+ this.mailbox.queue(() -> {
++ this.priorityChanges.add(() -> {
+ ChunkLightQueue remove = this.queue.buckets[currentPriority].remove(pair);
+ if (remove != null) {
+ ChunkLightQueue existing = this.queue.buckets[priority].put(pair, remove);
@@ -1121,6 +1121,15 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ });
+ }
+
++ private boolean isChunkLightStatus(long pair) {
++ PlayerChunk playerChunk = playerChunkMap.getUpdatingChunk(pair);
++ if (playerChunk == null) {
++ return false;
++ }
++ ChunkStatus status = PlayerChunk.getChunkStatus(playerChunk.getTicketLevel());
++ return status != null && status.isAtLeastStatus(ChunkStatus.LIGHT);
++ }
++
+ static class ChunkLightQueue {
+ public boolean shouldFastUpdate;
+ java.util.ArrayDeque<Runnable> pre = new java.util.ArrayDeque<Runnable>();
@@ -1131,7 +1140,7 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+
+
+ // Retain the chunks priority level for queued light tasks
-+ private static class LightQueue {
++ private class LightQueue {
+ private int size = 0;
+ private int lowestPriority = MAX_PRIORITIES;
+ private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES];
@@ -1171,6 +1180,10 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+ }
+
+ public boolean poll(java.util.List<Runnable> pre, java.util.List<Runnable> post) {
++ Runnable run;
++ while ((run = priorityChanges.poll()) != null) {
++ run.run();
++ }
+ boolean hasWork = false;
+ it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = this.buckets;
+ while (lowestPriority < MAX_PRIORITIES && !isEmpty()) {
@@ -1196,50 +1209,69 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
+
+ private final LightQueue queue = new LightQueue();
+ // Paper end
- private final PlayerChunkMap d;
++ private final PlayerChunkMap d; private final PlayerChunkMap playerChunkMap; // Paper
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> e;
private volatile int f = 5;
-@@ -25,7 +115,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+ private final AtomicBoolean g = new AtomicBoolean();
+
+ public LightEngineThreaded(ILightAccess ilightaccess, PlayerChunkMap playerchunkmap, boolean flag, ThreadedMailbox<Runnable> threadedmailbox, Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailbox) {
super(ilightaccess, true, flag);
- this.d = playerchunkmap;
+- this.d = playerchunkmap;
++ this.d = playerchunkmap; this.playerChunkMap = d; // Paper
this.e = mailbox;
-- this.b = threadedmailbox;
-+ this.mailbox = this.b = threadedmailbox; // Paper
+ this.b = threadedmailbox;
}
-
- public void close() {}
-@@ -111,8 +201,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+@@ -111,10 +215,10 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
- if (this.c.size() >= this.f) {
+- this.b();
+- }
+ // Paper start
+ int priority = intsupplier.getAsInt();
-+ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable); // Paper
-+ if (priority <= 25) { // don't auto kick off unless priority
-+ // Paper end
- this.b();
- }
++ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable);
++ // Paper end
-@@ -134,7 +227,14 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+ }, ChunkCoordIntPair.pair(i, j), intsupplier));
+ }
+@@ -133,8 +237,27 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+ public CompletableFuture<IChunkAccess> a(IChunkAccess ichunkaccess, boolean flag) {
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
- ichunkaccess.b(false);
+- ichunkaccess.b(false);
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
+ // Paper start
++ //ichunkaccess.b(false); // Don't need to disable this
+ long pair = chunkcoordintpair.pair();
+ CompletableFuture<IChunkAccess> future = new CompletableFuture<>();
-+ IntSupplier prioritySupplier1 = d.getPrioritySupplier(pair);
-+ IntSupplier prioritySupplier = flag ? () -> Math.max(1, prioritySupplier1.getAsInt() - 10) : prioritySupplier1;
++ IntSupplier prioritySupplier = playerChunkMap.getPrioritySupplier(pair);
+ this.e.a(ChunkTaskQueueSorter.a(() -> {
++ // Chunk's no longer needed
++ if (!isChunkLightStatus(pair)) {
++ this.d.c(chunkcoordintpair); // copied from end of method to release light ticket
++ future.complete(ichunkaccess);
++ return;
++ }
++ boolean[] skippedPre = {false};
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
++ if (!isChunkLightStatus(pair)) {
++ this.d.c(chunkcoordintpair); // copied from end of method to release light ticket
++ future.complete(ichunkaccess);
++ skippedPre[0] = true;
++ return;
++ }
+ // Paper end
ChunkSection[] achunksection = ichunkaccess.getSections();
for (int i = 0; i < 16; ++i) {
-@@ -155,52 +255,51 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
- this.d.c(chunkcoordintpair);
+@@ -152,55 +275,55 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+ });
+ }
+
+- this.d.c(chunkcoordintpair);
++ this.d.c(chunkcoordintpair); // Paper - if change, copy into !isChunkLightStatus above
}, () -> {
return "lightChunk " + chunkcoordintpair + " " + flag;
+ // Paper start - merge the 2 together
@@ -1247,6 +1279,7 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..9ef39f1f51f9960865f6418115b08e8d
- return CompletableFuture.supplyAsync(() -> {
+
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.POST_UPDATE, () -> {
++ if (skippedPre[0]) return; // Paper - future's already complete
ichunkaccess.b(true);
super.b(chunkcoordintpair, false);
- return ichunkaccess;