From 4bff48bda3c4df4e6896391c5c99aac244f1d070 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 1 Mar 2016 23:09:29 -0600 Subject: [PATCH] Further improve server tick loop Improves how the catchup buffer is handled, allowing it to roll both ways increasing the effeciency of the thread sleep so it only will sleep once. Also increases the buffer of the catchup to ensure server stays at 20 TPS unless extreme conditions Previous implementation did not calculate TPS correctly. Switch to a realistic rolling average and factor in std deviation as an extra reporting variable diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 13a0918cea..320af3f503 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -150,7 +150,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; public File bukkitDataPackFolder; @@ -160,7 +160,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 2000L && this.nextTick - this.lastOverloadTime >= 15000L) { - long j = i / 50L; - - if (server.getWarnOnOverload()) // CraftBukkit - MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j); - this.nextTick += j * 50L; - this.lastOverloadTime = this.nextTick; + curTime = System.nanoTime(); + // Paper start - Further improve server tick loop + wait = TICK_TIME - (curTime - lastTick); + if (wait > 0) { + if (catchupTime < 2E6) { + wait += Math.abs(catchupTime); + } else if (wait < catchupTime) { + catchupTime -= wait; + wait = 0; + } else { + wait -= catchupTime; + catchupTime = 0; + } + } + if (wait > 0) { + Thread.sleep(wait / 1000000); + curTime = System.nanoTime(); + wait = TICK_TIME - (curTime - lastTick); } - if ( tickCount++ % SAMPLE_INTERVAL == 0 ) + catchupTime = Math.min(MAX_CATCHUP_BUFFER, catchupTime - wait); + if ( ++MinecraftServer.currentTick % SAMPLE_INTERVAL == 0 ) { - double currentTps = 1E3 / ( curTime - tickSection ) * SAMPLE_INTERVAL; - 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) + final long diff = curTime - tickSection; + java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP); + tps1.add(currentTps, diff); + tps5.add(currentTps, diff); + tps15.add(currentTps, diff); + // Backwards compat with bad plugins + recentTps[0] = tps1.getAverage(); + recentTps[1] = tps5.getAverage(); + recentTps[2] = tps15.getAverage(); + // Paper end tickSection = curTime; } // Spigot end - MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit + //MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time + this.a(this::canSleepForTick); this.nextTick += 50L; if (this.T) { this.T = false; @@ -861,8 +930,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString() + ( ( tps > 20.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 ); -- 2.21.0