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/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java index 5fdaefc128956581be4bb9b34199fd6410563991..b7edc1121797bc1c57e25f540ed0124fa8b36b7a 100644 --- a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java +++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java @@ -312,6 +312,7 @@ public final class PaperTickList extends ServerTickList { // extend to avo toTick.tickState = STATE_SCHEDULED; this.addToNotTickingReady(toTick); } + MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick } catch (final Throwable thr) { // start copy from TickListServer // TODO check on update CrashReport crashreport = CrashReport.forThrowable(thr, "Exception while ticking"); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 71181012314d20e3505543a6d2abe88cb8e17a27..4778d45d14317d78ae1988de18f675d997d28c98 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -330,6 +330,76 @@ 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 + public MinecraftServer(OptionSet options, DataPackConfig datapackconfiguration, Thread thread, RegistryAccess.RegistryHolder iregistrycustom_dimension, LevelStorageSource.LevelStorageAccess convertable_conversionsession, WorldData savedata, PackRepository resourcepackrepository, Proxy proxy, DataFixer datafixer, ServerResources datapackresources, @Nullable MinecraftSessionService minecraftsessionservice, @Nullable GameProfileRepository gameprofilerepository, @Nullable GameProfileCache usercache, ChunkProgressListenerFactory worldloadlistenerfactory) { super("Server"); SERVER = this; // Paper - better singleton @@ -1325,6 +1395,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop dragonParts; private final StructureFeatureManager structureFeatureManager; 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; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index bdd50c28a76576be7950e3ccf8e00b622f3860d1..6818de8db716a3d4bcf8a6ee4dc6acccf441cddb 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -914,6 +914,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