From 38c90d242492d0cfde51dd8b543f8d281165be41 Mon Sep 17 00:00:00 2001 From: Martijn Muijsers Date: Tue, 31 Jan 2023 19:11:50 +0100 Subject: [PATCH] Split server tick steps --- patches/server/0157-Split-tick-steps.patch | 179 +++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 patches/server/0157-Split-tick-steps.patch diff --git a/patches/server/0157-Split-tick-steps.patch b/patches/server/0157-Split-tick-steps.patch new file mode 100644 index 0000000..5398c09 --- /dev/null +++ b/patches/server/0157-Split-tick-steps.patch @@ -0,0 +1,179 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martijn Muijsers +Date: Tue, 31 Jan 2023 19:05:12 +0100 +Subject: [PATCH] Split tick steps + +License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html) +Gale - https://galemc.org + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 7ed820d2483bf6741a355b062f062a04866ba938..9e645dce4b4187797b74369219dfb5078b04aea2 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1577,14 +1577,52 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + } + + public void tickChildren(BooleanSupplier shouldKeepTicking) { ++ // Gale start - split tick steps ++ this.doSchedulerHeartbeat(); ++ this.tickFunctions(); ++ //Iterator iterator = this.getAllLevels().iterator(); // Paper - moved down ++ this.runProcessQueueTasks(); ++ for (final ServerLevel world : this.getAllLevelsArray()) { // Gale - base thread pool - optimize server levels ++ this.updateTime(world); ++ } ++ this.isIteratingOverLevels = true; // Paper ++ for (ServerLevel worldserver : this.getAllLevelsArray()) { // Paper - move down // Gale - base thread pool - optimize server levels ++ this.updateEvents(worldserver); ++ try { ++ this.tickWorld(worldserver, shouldKeepTicking); ++ this.recalculateRegions(worldserver); ++ } catch (Throwable throwable) { ++ this.catchWorldTickException(worldserver, throwable); ++ } ++ this.clearExplosionDensity(worldserver); ++ } ++ this.isIteratingOverLevels = false; // Paper ++ this.tickConnection(); ++ this.tickPlayerList(); ++ if (SharedConstants.IS_RUNNING_IN_IDE) { ++ this.tickGameTestTicker(); ++ } ++ this.runTickables(); ++ } ++ ++ private void doSchedulerHeartbeat() { ++ // Gale end - split tick steps + MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper + this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit + MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper ++ // Gale start - split tick steps ++ } ++ ++ private void tickFunctions() { ++ // Gale end - split tick steps + MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper + this.getFunctions().tick(); + MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper +- //Iterator iterator = this.getAllLevels().iterator(); // Paper - moved down ++ // Gale start - split tick steps ++ } + ++ private void runProcessQueueTasks() { ++ // Gale end - split tick steps + // CraftBukkit start + // Run tasks that are waiting on processing + MinecraftTimings.processQueueTimer.startTiming(); // Spigot +@@ -1592,11 +1630,14 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + this.processQueue.remove().run(); + } + MinecraftTimings.processQueueTimer.stopTiming(); // Spigot ++ // Gale start - split tick steps ++ } + ++ private void updateTime(ServerLevel world) { ++ // Gale end - split tick steps + MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper + // Send time updates to everyone, it will get the right time from the world the player is in. + // Paper start - optimize time updates +- for (final ServerLevel world : this.getAllLevelsArray()) { // Gale - base thread pool - optimize server levels + final boolean doDaylight = world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT); + final long dayTime = world.getDayTime(); + long worldTime = world.getGameTime(); +@@ -1611,15 +1652,17 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + new ClientboundSetTimePacket(worldTime, playerTime, doDaylight); + entityplayer.connection.send(packet); // Add support for per player time + } +- } + // Paper end + MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper ++ // Gale start - split tick steps ++ } + +- this.isIteratingOverLevels = true; // Paper +- for (ServerLevel worldserver : this.getAllLevelsArray()) { // Paper - move down // Gale - base thread pool - optimize server levels ++ private void updateEvents(ServerLevel worldserver) { ++ // Gale end - split tick steps + worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper + worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper + net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper ++ } // Gale - split tick steps + + /* Drop global time updates + if (this.tickCount % 20 == 0) { +@@ -1629,16 +1672,27 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + } + // CraftBukkit end */ + +- try { ++ private void tickWorld(ServerLevel worldserver, BooleanSupplier shouldKeepTicking) { // Gale - split tick steps + worldserver.timings.doTick.startTiming(); // Spigot + worldserver.tick(shouldKeepTicking); ++ // Gale start - split tick steps ++ worldserver.timings.doTick.stopTiming(); // Spigot ++ } ++ ++ private void recalculateRegions(ServerLevel worldserver) { ++ worldserver.timings.doTick.startTiming(); // Spigot ++ // Gale end - split tick steps + // Paper start + for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) { + regionManager.recalculateRegions(); + } +- // Paper end + worldserver.timings.doTick.stopTiming(); // Spigot +- } catch (Throwable throwable) { ++ // Paper end ++ // Gale start - split tick steps ++ } ++ ++ private void catchWorldTickException(ServerLevel worldserver, Throwable throwable) { ++ // Gale end - split tick steps + // Spigot Start + CrashReport crashreport; + try { +@@ -1651,22 +1705,39 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop + + worldserver.fillReportDetails(crashreport); + throw new ReportedException(crashreport); +- } ++ // Gale start - split tick steps ++ } + ++ private void clearExplosionDensity(ServerLevel worldserver) { ++ // Gale end - split tick steps + worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions +- } +- this.isIteratingOverLevels = false; // Paper ++ // Gale start - split tick steps ++ } + ++ private void tickConnection() { ++ // Gale end - split tick steps + MinecraftTimings.connectionTimer.startTiming(); // Spigot + this.getConnection().tick(); + MinecraftTimings.connectionTimer.stopTiming(); // Spigot ++ // Gale start - split tick steps ++ } ++ ++ private void tickPlayerList() { ++ // Gale end - split tick steps + MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper + this.playerList.tick(); + MinecraftTimings.playerListTimer.stopTiming(); // Spigot // Paper +- if (SharedConstants.IS_RUNNING_IN_IDE) { ++ // Gale start - split tick steps ++ } ++ ++ private void tickGameTestTicker() { ++ // Gale end - split tick steps + GameTestTicker.SINGLETON.tick(); +- } ++ // Gale start - split tick steps ++ } + ++ private void runTickables() { ++ // Gale end - split tick steps + MinecraftTimings.tickablesTimer.startTiming(); // Spigot // Paper + for (int i = 0; i < this.tickables.size(); ++i) { + ((Runnable) this.tickables.get(i)).run();