From 8568fc2b9e771d97145d1d8ab20c43332d62c2a9 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 10 Jan 2013 00:18:11 -0500 Subject: [PATCH] Spigot Timings Overhauls the Timings System adding performance tracking all around the Minecraft Server diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index 361535428..78b264a13 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -123,9 +123,11 @@ public class ChunkProviderServer extends IChunkProvider { } gameprofilerfiller.c("getChunkCacheMiss"); + world.timings.syncChunkLoadTimer.startTiming(); // Spigot CompletableFuture> completablefuture = this.getChunkFutureMainThread(i, j, chunkstatus, flag); this.serverThreadQueue.awaitTasks(completablefuture::isDone); + world.timings.syncChunkLoadTimer.stopTiming(); // Spigot ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; }, (playerchunk_failure) -> { @@ -344,12 +346,16 @@ public class ChunkProviderServer extends IChunkProvider { public void tick(BooleanSupplier booleansupplier) { this.world.getMethodProfiler().enter("purge"); + this.world.timings.doChunkMap.startTiming(); // Spigot this.chunkMapDistance.purgeTickets(); this.tickDistanceManager(); + this.world.timings.doChunkMap.stopTiming(); // Spigot this.world.getMethodProfiler().exitEnter("chunks"); this.tickChunks(); + this.world.timings.doChunkUnload.startTiming(); // Spigot this.world.getMethodProfiler().exitEnter("unload"); this.playerChunkMap.unloadChunks(booleansupplier); + this.world.timings.doChunkUnload.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); this.clearCache(); } @@ -396,7 +402,9 @@ public class ChunkProviderServer extends IChunkProvider { SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2); } + this.world.timings.doTickTiles.startTiming(); // Spigot this.world.a(chunk, k); + this.world.timings.doTickTiles.stopTiming(); // Spigot } } } @@ -410,7 +418,9 @@ public class ChunkProviderServer extends IChunkProvider { this.world.getMethodProfiler().exit(); } + this.world.timings.tracker.startTiming(); // Spigot this.playerChunkMap.g(); + this.world.timings.tracker.stopTiming(); // Spigot } private void a(long i, Consumer consumer) { diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java index df31a010a..bd47979e1 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -404,6 +404,7 @@ public class ChunkRegionLoader { private static void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) { NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10); World world = chunk.getWorld(); + world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot for (int i = 0; i < nbttaglist.size(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); @@ -415,6 +416,8 @@ public class ChunkRegionLoader { chunk.d(true); } + world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot + world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities", 10); for (int j = 0; j < nbttaglist1.size(); ++j) { @@ -432,6 +435,7 @@ public class ChunkRegionLoader { } } } + world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot } diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java index 80bfb9e8f..2a63e517b 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -26,6 +26,7 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.io.IoBuilder; import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.SpigotTimings; // Spigot import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.event.server.RemoteServerCommandEvent; // CraftBukkit end @@ -365,6 +366,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } public void handleCommandQueue() { + SpigotTimings.serverCommandTimer.startTiming(); // Spigot while (!this.serverCommandQueue.isEmpty()) { ServerCommand servercommand = (ServerCommand) this.serverCommandQueue.remove(0); @@ -379,6 +381,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer // CraftBukkit end } + SpigotTimings.serverCommandTimer.stopTiming(); // Spigot } @Override diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index ce250b964..6182670bf 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -31,6 +31,7 @@ import org.bukkit.craftbukkit.event.CraftPortalEvent; import org.bukkit.entity.Hanging; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Vehicle; +import org.spigotmc.CustomTimingsHandler; // Spigot import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; @@ -162,6 +163,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener { public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean forceExplosionKnockback; // SPIGOT-949 public boolean persistentInvisibility = false; + public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot public float getBukkitYaw() { return this.yaw; @@ -516,6 +518,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener { } public void move(EnumMoveType enummovetype, Vec3D vec3d) { + org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot if (this.noclip) { this.a(this.getBoundingBox().c(vec3d)); this.recalcPosition(); @@ -651,6 +654,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener { this.world.getMethodProfiler().exit(); } + org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot } protected BlockPosition ap() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index 4e8e59a2b..7eeeb7dfa 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -42,6 +42,8 @@ import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end +import org.bukkit.craftbukkit.SpigotTimings; // Spigot + public abstract class EntityLiving extends Entity { private static final UUID b = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); @@ -2355,6 +2357,7 @@ public abstract class EntityLiving extends Entity { @Override public void tick() { + SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot super.tick(); this.t(); this.v(); @@ -2403,7 +2406,9 @@ public abstract class EntityLiving extends Entity { } } + SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot this.movementTick(); + SpigotTimings.timerEntityTickRest.startTiming(); // Spigot double d0 = this.locX() - this.lastX; double d1 = this.locZ() - this.lastZ; float f = (float) (d0 * d0 + d1 * d1); @@ -2484,6 +2489,7 @@ public abstract class EntityLiving extends Entity { this.pitch = 0.0F; } + SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot } public void updateEquipment() { // PAIL private->public; updateEquipment @@ -2665,6 +2671,7 @@ public abstract class EntityLiving extends Entity { this.setMot(d4, d5, d6); this.world.getMethodProfiler().enter("ai"); + SpigotTimings.timerEntityAI.startTiming(); // Spigot if (this.isFrozen()) { this.jumping = false; this.aR = 0.0F; @@ -2674,6 +2681,7 @@ public abstract class EntityLiving extends Entity { this.doTick(); this.world.getMethodProfiler().exit(); } + SpigotTimings.timerEntityAI.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); this.world.getMethodProfiler().enter("jump"); @@ -2708,7 +2716,9 @@ public abstract class EntityLiving extends Entity { this.r(); AxisAlignedBB axisalignedbb = this.getBoundingBox(); + SpigotTimings.timerEntityAIMove.startTiming(); // Spigot this.g(new Vec3D((double) this.aR, (double) this.aS, (double) this.aT)); + SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); this.world.getMethodProfiler().enter("push"); if (this.bf > 0) { @@ -2716,7 +2726,9 @@ public abstract class EntityLiving extends Entity { this.a(axisalignedbb, this.getBoundingBox()); } + SpigotTimings.timerEntityAICollision.startTiming(); // Spigot this.collideNearby(); + SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); if (!this.world.isClientSide && this.dO() && this.aG()) { this.damageEntity(DamageSource.DROWN, 1.0F); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 87c51b9c3..5ef5a26ff 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -65,6 +65,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.Main; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end +import org.bukkit.craftbukkit.SpigotTimings; // Spigot public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable { @@ -958,6 +959,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit + SpigotTimings.worldSaveTimer.startTiming(); // Spigot MinecraftServer.LOGGER.debug("Autosave started"); this.methodProfiler.enter("save"); this.playerList.savePlayers(); this.saveChunks(true, false, false); this.methodProfiler.exit(); MinecraftServer.LOGGER.debug("Autosave finished"); + SpigotTimings.worldSaveTimer.stopTiming(); // Spigot } this.methodProfiler.enter("snooper"); @@ -1003,21 +1007,30 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant { return String.valueOf(TileEntityTypes.a(tileentity.getTileType())); }); + tileentity.tickTimer.startTiming(); // Spigot if (tileentity.getTileType().isValidBlock(this.getType(blockposition).getBlock())) { ((ITickable) tileentity).tick(); } else { @@ -618,6 +624,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { tileentity.a(crashreportsystemdetails); throw new ReportedException(crashreport); + // Spigot start + } finally { + tileentity.tickTimer.stopTiming(); + // Spigot end } } } @@ -631,6 +641,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { } } + timings.tileEntityTick.stopTiming(); // Spigot + timings.tileEntityPending.startTiming(); // Spigot this.tickingTileEntities = false; gameprofilerfiller.exitEnter("pendingBlockEntities"); if (!this.tileEntityListPending.isEmpty()) { @@ -663,12 +675,15 @@ public abstract class World implements GeneratorAccess, AutoCloseable { this.tileEntityListPending.clear(); } + timings.tileEntityPending.stopTiming(); // Spigot gameprofilerfiller.exit(); } public void a(Consumer consumer, Entity entity) { try { + SpigotTimings.tickEntityTimer.startTiming(); // Spigot consumer.accept(entity); + SpigotTimings.tickEntityTimer.stopTiming(); // Spigot } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Ticking entity"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked"); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java index ecff876d7..f30161f51 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -43,6 +43,7 @@ import org.apache.logging.log4j.Logger; import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.WeatherType; +import org.bukkit.craftbukkit.SpigotTimings; // Spigot import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.util.WorldUUID; import org.bukkit.event.entity.CreatureSpawnEvent; @@ -331,15 +332,19 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.exitEnter("chunkSource"); this.getChunkProvider().tick(booleansupplier); gameprofilerfiller.exitEnter("tickPending"); + timings.doTickPending.startTiming(); // Spigot if (!this.isDebugWorld()) { this.nextTickListBlock.b(); this.nextTickListFluid.b(); } + timings.doTickPending.stopTiming(); // Spigot gameprofilerfiller.exitEnter("raid"); this.persistentRaid.a(); gameprofilerfiller.exitEnter("blockEvents"); + timings.doSounds.startTiming(); // Spigot this.ak(); + timings.doSounds.stopTiming(); // Spigot this.ticking = false; gameprofilerfiller.exitEnter("entities"); boolean flag3 = true || !this.players.isEmpty() || !this.getForceLoadedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players @@ -349,6 +354,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } if (flag3 || this.emptyTime++ < 300) { + timings.tickEntities.startTiming(); // Spigot if (this.dragonBattle != null) { this.dragonBattle.b(); } @@ -356,6 +362,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.tickingEntities = true; ObjectIterator objectiterator = this.entitiesById.int2ObjectEntrySet().iterator(); + timings.entityTick.startTiming(); // Spigot while (objectiterator.hasNext()) { Entry entry = (Entry) objectiterator.next(); Entity entity = (Entity) entry.getValue(); @@ -400,6 +407,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.exit(); } + timings.entityTick.stopTiming(); // Spigot this.tickingEntities = false; @@ -409,6 +417,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.registerEntity(entity2); } + timings.tickEntities.stopTiming(); // Spigot this.tickBlockEntities(); } @@ -631,6 +640,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { if (!(entity instanceof EntityHuman) && !this.getChunkProvider().a(entity)) { this.chunkCheck(entity); } else { + entity.tickTimer.startTiming(); // Spigot entity.g(entity.locX(), entity.locY(), entity.locZ()); entity.lastYaw = entity.yaw; entity.lastPitch = entity.pitch; @@ -657,6 +667,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.a(entity, entity1); } } + entity.tickTimer.stopTiming(); // Spigot } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 27b4683a2..d802b248b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2033,6 +2033,11 @@ public final class CraftServer implements Server { private final Spigot spigot = new Spigot() { + @Override + public YamlConfiguration getConfig() + { + return org.spigotmc.SpigotConfig.config; + } }; public Spigot spigot() diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java new file mode 100644 index 000000000..311e451b2 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java @@ -0,0 +1,160 @@ +package org.bukkit.craftbukkit; + +import java.util.HashMap; +import net.minecraft.server.Entity; +import net.minecraft.server.TileEntity; +import net.minecraft.server.World; +import net.minecraft.server.WorldDataServer; +import org.bukkit.craftbukkit.scheduler.CraftTask; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.bukkit.scheduler.BukkitTask; +import org.spigotmc.CustomTimingsHandler; + +public class SpigotTimings { + + public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick"); + public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List"); + public static final CustomTimingsHandler commandFunctionsTimer = new CustomTimingsHandler("Command Functions"); + public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler"); + public static final CustomTimingsHandler playerConnectionTimer = new CustomTimingsHandler("** PlayerConnection"); + public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables"); + public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler"); + public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update"); + public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command"); + public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save"); + + public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove"); + public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity"); + public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity"); + public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity"); + + public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick"); + public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI"); + public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision"); + public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove"); + public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest"); + + public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue"); + public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer); + + public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand"); + + public static final HashMap entityTypeTimingMap = new HashMap(); + public static final HashMap tileEntityTypeTimingMap = new HashMap(); + public static final HashMap pluginTaskTimingMap = new HashMap(); + + /** + * Gets a timer associated with a plugins tasks. + * @param task + * @param period + * @return + */ + public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) { + if (!task.isSync()) { + return null; + } + String plugin; + final CraftTask ctask = (CraftTask) task; + + if (task.getOwner() != null) { + plugin = task.getOwner().getDescription().getFullName(); + } else { + plugin = "Unknown"; + } + String taskname = ctask.getTaskName(); + + String name = "Task: " + plugin + " Runnable: " + taskname; + if (period > 0) { + name += "(interval:" + period + ")"; + } else { + name += "(Single)"; + } + CustomTimingsHandler result = pluginTaskTimingMap.get(name); + if (result == null) { + result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer); + pluginTaskTimingMap.put(name, result); + } + return result; + } + + /** + * Get a named timer for the specified entity type to track type specific timings. + * @param entity + * @return + */ + public static CustomTimingsHandler getEntityTimings(Entity entity) { + String entityType = entity.getClass().getName(); + CustomTimingsHandler result = entityTypeTimingMap.get(entityType); + if (result == null) { + result = new CustomTimingsHandler("** tickEntity - " + entity.getClass().getSimpleName(), activatedEntityTimer); + entityTypeTimingMap.put(entityType, result); + } + return result; + } + + /** + * Get a named timer for the specified tile entity type to track type specific timings. + * @param entity + * @return + */ + public static CustomTimingsHandler getTileEntityTimings(TileEntity entity) { + String entityType = entity.getClass().getName(); + CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType); + if (result == null) { + result = new CustomTimingsHandler("** tickTileEntity - " + entity.getClass().getSimpleName(), tickTileEntityTimer); + tileEntityTypeTimingMap.put(entityType, result); + } + return result; + } + + /** + * Set of timers per world, to track world specific timings. + */ + public static class WorldTimingsHandler { + public final CustomTimingsHandler mobSpawn; + public final CustomTimingsHandler doChunkUnload; + public final CustomTimingsHandler doTickPending; + public final CustomTimingsHandler doTickTiles; + public final CustomTimingsHandler doChunkMap; + public final CustomTimingsHandler doSounds; + public final CustomTimingsHandler entityTick; + public final CustomTimingsHandler tileEntityTick; + public final CustomTimingsHandler tileEntityPending; + public final CustomTimingsHandler tracker; + public final CustomTimingsHandler doTick; + public final CustomTimingsHandler tickEntities; + + public final CustomTimingsHandler syncChunkLoadTimer; + public final CustomTimingsHandler syncChunkLoadStructuresTimer; + public final CustomTimingsHandler syncChunkLoadEntitiesTimer; + public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer; + public final CustomTimingsHandler syncChunkLoadTileTicksTimer; + public final CustomTimingsHandler syncChunkLoadPostTimer; + + public WorldTimingsHandler(World server) { + String name = ((WorldDataServer) server.worldData).getName() + " - "; + + mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn"); + doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload"); + doTickPending = new CustomTimingsHandler("** " + name + "doTickPending"); + doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles"); + doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap"); + doSounds = new CustomTimingsHandler("** " + name + "doSounds"); + entityTick = new CustomTimingsHandler("** " + name + "entityTick"); + tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick"); + tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending"); + + syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad"); + syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures"); + syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities"); + syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities"); + syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks"); + syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post"); + + + tracker = new CustomTimingsHandler(name + "tracker"); + doTick = new CustomTimingsHandler(name + "doTick"); + tickEntities = new CustomTimingsHandler(name + "tickEntities"); + } + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java index ce2e3d282..9ad17c560 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -396,7 +396,9 @@ public class CraftScheduler implements BukkitScheduler { if (task.isSync()) { currentTask = task; try { + task.timings.startTiming(); // Spigot task.run(); + task.timings.stopTiming(); // Spigot } catch (final Throwable throwable) { task.getOwner().getLogger().log( Level.WARNING, diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java index a85fbbb69..a8ce875f8 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java @@ -4,9 +4,11 @@ import java.util.function.Consumer; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitTask; +import org.bukkit.craftbukkit.SpigotTimings; // Spigot +import org.spigotmc.CustomTimingsHandler; // Spigot -class CraftTask implements BukkitTask, Runnable { +public class CraftTask implements BukkitTask, Runnable { // Spigot private volatile CraftTask next = null; public static final int ERROR = 0; @@ -29,6 +31,7 @@ class CraftTask implements BukkitTask, Runnable { private final Plugin plugin; private final int id; + final CustomTimingsHandler timings; // Spigot CraftTask() { this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING); } @@ -54,6 +57,7 @@ class CraftTask implements BukkitTask, Runnable { } this.id = id; this.period = period; + this.timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null; // Spigot } @Override @@ -127,4 +131,10 @@ class CraftTask implements BukkitTask, Runnable { setPeriod(CraftTask.CANCEL); return true; } + + // Spigot start + public String getTaskName() { + return (getTaskClass() == null) ? "Unknown" : getTaskClass().getName(); + } + // Spigot end } -- 2.25.1