From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 6 Apr 2020 04:20:44 -0700 Subject: [PATCH] Execute chunk tasks mid-tick This will help the server load chunks if tick times are high. diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java index b27021a42cbed3f0648a8d0903d00d03922ae221..eada966d7f108a6081be7a848f5c1dfcb1eed676 100644 --- a/src/main/java/co/aikar/timings/MinecraftTimings.java +++ b/src/main/java/co/aikar/timings/MinecraftTimings.java @@ -45,6 +45,8 @@ public final class MinecraftTimings { public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); + public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks"); + private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); private MinecraftTimings() {} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 8aaf73d24ddff65c45eeb18d573e20fb8a1439a5..fddb279d161b30d6944495f0de9f6b7e21761a80 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1344,6 +1344,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= MAX_CHUNK_EXEC_TIME) { + if (!moreTasks) { + lastMidTickExecuteFailure = currTime; + } + + // note: negative values reduce the time + long overuse = diff - MAX_CHUNK_EXEC_TIME; + if (overuse >= (10L * 1000L * 1000L)) { // 10ms + // make sure something like a GC or dumb plugin doesn't screw us over... + overuse = 10L * 1000L * 1000L; // 10ms + } + + double overuseCount = (double)overuse/(double)MAX_CHUNK_EXEC_TIME; + long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME); + + lastMidTickExecute = currTime + extraSleep; + return; + } + } + } finally { + co.aikar.timings.MinecraftTimings.midTickChunkTasks.stopTiming(); + } + } + // Paper end - execute chunk tasks mid tick } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index d06ad4f2c76eebd3b8191f3de6c0199fa3bb5f22..e14215d538d19838041e3e21a84396c2f31ecd8e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -1011,6 +1011,7 @@ public class ServerChunkCache extends ChunkSource { iterator1 = shuffled.iterator(); } + int chunksTicked = 0; // Paper try { while (iterator1.hasNext()) { LevelChunk chunk1 = iterator1.next(); @@ -1028,6 +1029,7 @@ public class ServerChunkCache extends ChunkSource { if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { this.level.tickChunk(chunk1, k); + if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper } } // Paper start - optimise chunk tick iteration diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 4800285c5a6262d2f3331a10bb262e37489a47fa..cb872bcd9aba263ec2233aa1555bc99133cc682c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -202,7 +202,9 @@ public class ServerLevel extends Level implements WorldGenLevel { private final StructureFeatureManager structureFeatureManager; private final StructureCheck structureCheck; private final boolean tickTime; - + // Paper start - execute chunk tasks mid tick + public long lastMidTickExecuteFailure; + // Paper end - execute chunk tasks mid tick // CraftBukkit start private int tickPosition; @@ -965,6 +967,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (fluid1.is(fluid)) { fluid1.tick(this, pos); } + MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick } @@ -974,6 +977,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } + MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 944519c4433710610ac5015d3d3de380d9ec39c9..06035b728a66a63582c34c85096bada1588bfaa6 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -838,6 +838,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Spigot end } else if (this.shouldTickBlocksAt(ChunkPos.asLong(tickingblockentity.getPos()))) { tickingblockentity.tick(); + // Paper start - execute chunk tasks during tick + if ((this.tileTickPosition & 7) == 0) { + MinecraftServer.getServer().executeMidTickTasks(); + } + // Paper end - execute chunk tasks during tick } } this.blockEntityTickers.removeAll(toRemove); @@ -852,6 +857,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public void guardEntityTick(Consumer tickConsumer, T entity) { try { tickConsumer.accept(entity); + MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick } catch (Throwable throwable) { if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes