From 62d962ce014ab160b743d03ba2796c1b72fa1f1d Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 28 Dec 2021 07:19:01 -0800 Subject: [PATCH] Execute chunk tasks fairly for worlds while waiting for next tick Currently, only the first world would have had tasks executed. This might result in chunks loading far slower in the nether, for example. --- .../server/MinecraftServer.java.patch | 96 +++++++++++-------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index 24e98144bc..7e79b65d7f 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -555,12 +555,10 @@ if (!iworlddataserver.isInitialized()) { try { -@@ -425,32 +715,10 @@ - } - +@@ -427,30 +717,8 @@ iworlddataserver.setInitialized(true); -- } -- + } + - this.getPlayerList().addWorldborderListener(worldserver); - if (this.worldData.getCustomBossEvents() != null) { - this.getCustomBossEvents().load(this.worldData.getCustomBossEvents(), this.registryAccess()); @@ -581,8 +579,8 @@ - worldborder.addListener(new BorderChangeListener.DelegateBorderChangeListener(worldserver1.getWorldBorder())); - this.levels.put(resourcekey1, worldserver1); - } - } - +- } +- - worldborder.applySettings(iworlddataserver.getWorldBorder()); } + // CraftBukkit end @@ -861,7 +859,7 @@ while (this.running) { long i; -@@ -744,11 +1152,30 @@ +@@ -744,12 +1152,31 @@ if (j > MinecraftServer.OVERLOADED_THRESHOLD_NANOS + 20L * i && this.nextTickTimeNanos - this.lastOverloadWarningNanos >= MinecraftServer.OVERLOADED_WARNING_INTERVAL_NANOS + 100L * i) { long k = j / i; @@ -870,7 +868,7 @@ this.nextTickTimeNanos += k * i; this.lastOverloadWarningNanos = this.nextTickTimeNanos; } -+ } + } + // Spigot start + // Paper start - further improve server tick loop + currentTime = Util.getNanos(); @@ -880,18 +878,19 @@ + tps1.add(currentTps, diff); + tps5.add(currentTps, diff); + tps15.add(currentTps, diff); -+ + + // Backwards compat with bad plugins + this.recentTps[0] = tps1.getAverage(); + this.recentTps[1] = tps5.getAverage(); + this.recentTps[2] = tps15.getAverage(); + tickSection = currentTime; - } ++ } + // Paper end - further improve server tick loop + // Spigot end - ++ boolean flag = i == 0L; + if (this.debugCommandProfilerDelayStart) { @@ -757,6 +1184,8 @@ this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount); } @@ -942,7 +941,26 @@ } @Override -@@ -977,7 +1420,7 @@ +@@ -961,6 +1404,7 @@ + if (super.pollTask()) { + return true; + } else { ++ boolean ret = false; // Paper - force execution of all worlds, do not just bias the first + if (this.tickRateManager.isSprinting() || this.haveTime()) { + Iterator iterator = this.getAllLevels().iterator(); + +@@ -968,16 +1412,16 @@ + ServerLevel worldserver = (ServerLevel) iterator.next(); + + if (worldserver.getChunkSource().pollTask()) { +- return true; ++ ret = true; // Paper - force execution of all worlds, do not just bias the first + } + } + } + +- return false; ++ return ret; // Paper - force execution of all worlds, do not just bias the first } } @@ -951,7 +969,7 @@ Profiler.get().incrementCounter("runTask"); super.doRunTask(ticktask); } -@@ -1025,6 +1468,7 @@ +@@ -1025,6 +1469,7 @@ } public void tickServer(BooleanSupplier shouldKeepTicking) { @@ -959,7 +977,7 @@ long i = Util.getNanos(); int j = this.pauseWhileEmptySeconds() * 20; -@@ -1041,11 +1485,13 @@ +@@ -1041,11 +1486,13 @@ this.autoSave(); } @@ -973,7 +991,7 @@ ++this.tickCount; this.tickRateManager.tick(); this.tickChildren(shouldKeepTicking); -@@ -1055,12 +1501,18 @@ +@@ -1055,12 +1502,18 @@ } --this.ticksUntilAutosave; @@ -993,7 +1011,7 @@ gameprofilerfiller.push("tallying"); long k = Util.getNanos() - i; int l = this.tickCount % 100; -@@ -1069,12 +1521,17 @@ +@@ -1069,12 +1522,17 @@ this.aggregatedTickTimesNanos += k; this.tickTimesNanos[l] = k; this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float) k / (float) TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; @@ -1012,7 +1030,7 @@ MinecraftServer.LOGGER.debug("Autosave started"); ProfilerFiller gameprofilerfiller = Profiler.get(); -@@ -1123,7 +1580,7 @@ +@@ -1123,7 +1581,7 @@ private ServerStatus buildServerStatus() { ServerStatus.Players serverping_serverpingplayersample = this.buildPlayerStatus(); @@ -1021,7 +1039,7 @@ } private ServerStatus.Players buildPlayerStatus() { -@@ -1133,7 +1590,7 @@ +@@ -1133,7 +1591,7 @@ if (this.hidesOnlinePlayers()) { return new ServerStatus.Players(i, list.size(), List.of()); } else { @@ -1030,7 +1048,7 @@ ObjectArrayList objectarraylist = new ObjectArrayList(j); int k = Mth.nextInt(this.random, 0, list.size() - j); -@@ -1154,24 +1611,56 @@ +@@ -1154,24 +1612,56 @@ this.getPlayerList().getPlayers().forEach((entityplayer) -> { entityplayer.connection.suspendFlushing(); }); @@ -1040,13 +1058,13 @@ this.getFunctions().tick(); gameprofilerfiller.popPush("levels"); Iterator iterator = this.getAllLevels().iterator(); - ++ + // CraftBukkit start + // Run tasks that are waiting on processing + while (!this.processQueue.isEmpty()) { + this.processQueue.remove().run(); + } -+ + + // Send time updates to everyone, it will get the right time from the world the player is in. + // Paper start - Perf: Optimize time updates + for (final ServerLevel level : this.getAllLevels()) { @@ -1087,7 +1105,7 @@ gameprofilerfiller.push("tick"); -@@ -1186,6 +1675,7 @@ +@@ -1186,6 +1676,7 @@ gameprofilerfiller.pop(); gameprofilerfiller.pop(); @@ -1095,7 +1113,7 @@ } gameprofilerfiller.popPush("connection"); -@@ -1267,6 +1757,22 @@ +@@ -1267,6 +1758,22 @@ return (ServerLevel) this.levels.get(key); } @@ -1118,7 +1136,7 @@ public Set> levelKeys() { return this.levels.keySet(); } -@@ -1296,7 +1802,7 @@ +@@ -1296,7 +1803,7 @@ @DontObfuscate public String getServerModName() { @@ -1127,7 +1145,7 @@ } public SystemReport fillSystemReport(SystemReport details) { -@@ -1347,7 +1853,7 @@ +@@ -1347,7 +1854,7 @@ @Override public void sendSystemMessage(Component message) { @@ -1136,7 +1154,7 @@ } public KeyPair getKeyPair() { -@@ -1385,11 +1891,14 @@ +@@ -1385,11 +1892,14 @@ } } @@ -1156,7 +1174,7 @@ } } -@@ -1403,7 +1912,7 @@ +@@ -1403,7 +1913,7 @@ while (iterator.hasNext()) { ServerLevel worldserver = (ServerLevel) iterator.next(); @@ -1165,7 +1183,7 @@ } } -@@ -1481,10 +1990,20 @@ +@@ -1481,10 +1991,20 @@ @Override public String getMotd() { @@ -1187,7 +1205,7 @@ this.motd = motd; } -@@ -1507,7 +2026,7 @@ +@@ -1507,7 +2027,7 @@ } public ServerConnectionListener getConnection() { @@ -1196,7 +1214,7 @@ } public boolean isReady() { -@@ -1632,13 +2151,19 @@ +@@ -1632,13 +2152,19 @@ return this.functionManager; } @@ -1218,7 +1236,7 @@ }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess()); -@@ -1654,6 +2179,7 @@ +@@ -1654,6 +2180,7 @@ }).thenAcceptAsync((minecraftserver_reloadableresources) -> { this.resources.close(); this.resources = minecraftserver_reloadableresources; @@ -1226,7 +1244,7 @@ this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -1665,6 +2191,8 @@ +@@ -1665,6 +2192,8 @@ this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary()); this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager); this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures()); @@ -1235,7 +1253,7 @@ }, this); if (this.isSameThread()) { -@@ -1789,14 +2317,15 @@ +@@ -1789,14 +2318,15 @@ if (this.isEnforceWhitelist()) { PlayerList playerlist = source.getServer().getPlayerList(); UserWhiteList whitelist = playerlist.getWhiteList(); @@ -1253,7 +1271,7 @@ } } -@@ -1952,7 +2481,7 @@ +@@ -1952,7 +2482,7 @@ final List list = Lists.newArrayList(); final GameRules gamerules = this.getGameRules(); @@ -1262,7 +1280,7 @@ @Override public > void visit(GameRules.Key key, GameRules.Type type) { list.add(String.format(Locale.ROOT, "%s=%s\n", key.getId(), gamerules.getRule(key))); -@@ -2058,7 +2587,7 @@ +@@ -2058,7 +2588,7 @@ try { label51: { @@ -1271,7 +1289,7 @@ try { arraylist = Lists.newArrayList(NativeModuleLister.listModules()); -@@ -2108,6 +2637,21 @@ +@@ -2108,6 +2638,21 @@ } @@ -1293,7 +1311,7 @@ private ProfilerFiller createProfiler() { if (this.willStartRecordingMetrics) { this.metricsRecorder = ActiveMetricsRecorder.createStarted(new ServerMetricsSamplersProvider(Util.timeSource, this.isDedicatedServer()), Util.timeSource, Util.ioPool(), new MetricsPersister("server"), this.onMetricsRecordingStopped, (path) -> { -@@ -2225,18 +2769,24 @@ +@@ -2225,18 +2770,24 @@ } public void logChatMessage(Component message, ChatType.Bound params, @Nullable String prefix) { @@ -1322,7 +1340,7 @@ } public boolean logIPs() { -@@ -2379,4 +2929,30 @@ +@@ -2379,4 +2930,30 @@ public static record ServerResourcePackInfo(UUID id, String url, String hash, boolean isRequired, @Nullable Component prompt) { }