From a50a1d4c83dbda8ca9e362c744eaba8ac3fc3159 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 25 Jan 2014 14:09:21 +1100 Subject: [PATCH] Implement a new TPS command which will show the average TPS over the last 1,5 and 15 minutes, using the same algorithm as the linux kernel (exponentiallialy damped moving average). --- .../0100-Highly-Optimized-Tick-Loop.patch | 158 ++++++++++-------- 1 file changed, 89 insertions(+), 69 deletions(-) diff --git a/CraftBukkit-Patches/0100-Highly-Optimized-Tick-Loop.patch b/CraftBukkit-Patches/0100-Highly-Optimized-Tick-Loop.patch index 4b262cd3d..13ee2fc64 100644 --- a/CraftBukkit-Patches/0100-Highly-Optimized-Tick-Loop.patch +++ b/CraftBukkit-Patches/0100-Highly-Optimized-Tick-Loop.patch @@ -1,11 +1,11 @@ -From a6907b6a5936948036e02fdc6ce81f554bb787e9 Mon Sep 17 00:00:00 2001 +From ad6ccb8e038d440644721c1d4e586875230ad444 Mon Sep 17 00:00:00 2001 From: md_5 -Date: Wed, 22 Jan 2014 19:14:15 +1100 +Date: Sat, 25 Jan 2014 14:08:35 +1100 Subject: [PATCH] Highly Optimized Tick Loop diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 588ce0a..0ca1bb6 100644 +index 588ce0a..a549a95 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -101,6 +101,11 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo @@ -15,12 +15,26 @@ index 588ce0a..0ca1bb6 100644 + // Spigot start + private static final int TPS = 20; + private static final int TICK_TIME = 1000000000 / TPS; -+ public static double currentTPS = 0; ++ public final double[] recentTps = new double[ 3 ]; + // Spigot end public MinecraftServer(OptionSet options, Proxy proxy) { // CraftBukkit - signature file -> OptionSet i = this; -@@ -429,38 +434,25 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo +@@ -419,6 +424,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo + this.isRunning = false; + } + ++ // Spigot Start ++ private static double calcTps(double avg, double exp, double tps) ++ { ++ return ( avg * exp ) + ( tps * ( 1 - exp ) ); ++ } ++ // Spigot End ++ + public void run() { + try { + if (this.init()) { +@@ -429,38 +441,32 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo this.p.setServerInfo(new ServerPingServerData("1.7.2", 4)); this.a(this.p); @@ -40,32 +54,37 @@ index 588ce0a..0ca1bb6 100644 - if (l < 0L) { - h.warn("Time ran backwards! Did the system time change?"); - l = 0L; -- } -- -- j += l; -- i = k; -- if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit -- this.t(); -- j = 0L; + curTime = System.nanoTime(); + wait = TICK_TIME - (curTime - lastTick) - catchupTime; + if (wait > 0) { + Thread.sleep(wait / 1000000); + catchupTime = 0; + continue; - } else { ++ } else { ++ catchupTime = Math.min(1000000000, Math.abs(wait)); + } + +- j += l; +- i = k; +- if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit +- this.t(); +- j = 0L; +- } else { - while (j > 50L) { - MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit - j -= 50L; - this.t(); - } -+ catchupTime = Math.min(1000000000, Math.abs(wait)); ++ if ( MinecraftServer.currentTick++ % 100 == 0 ) ++ { ++ double currentTps = 1E9 / ( curTime - lastTick ); ++ recentTps[0] = calcTps( recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min) ++ recentTps[1] = calcTps( recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min) ++ recentTps[2] = calcTps( recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min) } -- -- Thread.sleep(1L); -+ currentTPS = (currentTPS * 0.95) + (1E9 / (curTime - lastTick) * 0.05); + lastTick = curTime; -+ MinecraftServer.currentTick++; + +- Thread.sleep(1L); + this.t(); this.N = true; } @@ -73,60 +92,11 @@ index 588ce0a..0ca1bb6 100644 } else { this.a((CrashReport) null); } -diff --git a/src/main/java/org/bukkit/craftbukkit/command/TicksPerSecondCommand.java b/src/main/java/org/bukkit/craftbukkit/command/TicksPerSecondCommand.java -new file mode 100644 -index 0000000..f114a31 ---- /dev/null -+++ b/src/main/java/org/bukkit/craftbukkit/command/TicksPerSecondCommand.java -@@ -0,0 +1,35 @@ -+package org.bukkit.craftbukkit.command; -+ -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.ChatColor; -+import org.bukkit.command.Command; -+import org.bukkit.command.CommandSender; -+ -+public class TicksPerSecondCommand extends Command { -+ -+ public TicksPerSecondCommand(String name) { -+ super(name); -+ this.description = "Gets the current ticks per second for the server"; -+ this.usageMessage = "/tps"; -+ this.setPermission("bukkit.command.tps"); -+ } -+ -+ @Override -+ public boolean execute(CommandSender sender, String currentAlias, String[] args) { -+ if (!testPermission(sender)) return true; -+ -+ double tps = Math.min(20, Math.round(MinecraftServer.currentTPS * 10) / 10.0); -+ ChatColor color; -+ if (tps > 19.2D) { -+ color = ChatColor.GREEN; -+ } else if (tps > 17.4D) { -+ color = ChatColor.YELLOW; -+ } else { -+ color = ChatColor.RED; -+ } -+ -+ sender.sendMessage(ChatColor.GOLD + "[TPS] " + color + tps); -+ -+ return true; -+ } -+} diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java -index 205249e..4319e9b 100755 +index 205249e..6634292 100755 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java -@@ -20,6 +20,7 @@ import org.bukkit.command.Command; - import org.bukkit.command.SimpleCommandMap; - import org.bukkit.configuration.ConfigurationSection; - import org.bukkit.configuration.file.YamlConfiguration; -+import org.bukkit.craftbukkit.command.TicksPerSecondCommand; - - public class SpigotConfig - { -@@ -248,4 +249,9 @@ public class SpigotConfig +@@ -248,4 +248,9 @@ public class SpigotConfig "screen." ); } } @@ -136,6 +106,56 @@ index 205249e..4319e9b 100755 + commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); + } } +diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java +new file mode 100644 +index 0000000..0f73608 +--- /dev/null ++++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java +@@ -0,0 +1,44 @@ ++package org.spigotmc; ++ ++import com.google.common.base.Joiner; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.util.com.google.common.collect.Iterables; ++import org.bukkit.ChatColor; ++import org.bukkit.command.Command; ++import org.bukkit.command.CommandSender; ++ ++public class TicksPerSecondCommand extends Command ++{ ++ ++ public TicksPerSecondCommand(String name) ++ { ++ super( name ); ++ this.description = "Gets the current ticks per second for the server"; ++ this.usageMessage = "/tps"; ++ this.setPermission( "bukkit.command.tps" ); ++ } ++ ++ @Override ++ public boolean execute(CommandSender sender, String currentAlias, String[] args) ++ { ++ if ( !testPermission( sender ) ) ++ { ++ return true; ++ } ++ ++ StringBuilder sb = new StringBuilder( ChatColor.GOLD + "Tps from last 1m, 5m, 15m: " ); ++ for ( double tps : MinecraftServer.getServer().recentTps ) ++ { ++ sb.append( format( Math.max( tps, 20 ) ) ); ++ sb.append( ", " ); ++ } ++ sender.sendMessage( sb.substring( 0, sb.length() - 2 ) ); ++ ++ return true; ++ } ++ ++ private String format(double tps) ++ { ++ return ( ( tps > 18 ) ? ChatColor.GREEN : ( tps > 16 ) ? ChatColor.YELLOW : ChatColor.RED ).toString() + tps; ++ } ++} -- 1.8.3.2