From 03b78b52c12f9a31029d38fb63b4f1db01e6a2c7 Mon Sep 17 00:00:00 2001 From: gnembon Date: Fri, 17 May 2019 23:58:33 -0300 Subject: [PATCH] tick complete --- .../java/carpet/commands/TickCommand.java | 4 +- .../mixins/MinecraftServer_motdMixin.java | 4 +- .../MinecraftServer_tickspeedMixin.java | 56 +-- .../mixins/ServerChunkManager_tickMixin.java | 64 +++ .../carpet/mixins/ServerWorld_tickMixin.java | 71 +++- .../java/carpet/mixins/World_tickMixin.java | 27 +- .../java/carpet/utils/CarpetProfiler.java | 369 ++++++++---------- src/main/resources/carpet.mixins.json | 4 + 8 files changed, 338 insertions(+), 261 deletions(-) create mode 100644 src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java diff --git a/src/main/java/carpet/commands/TickCommand.java b/src/main/java/carpet/commands/TickCommand.java index dbe9759d..5f2dcf8d 100644 --- a/src/main/java/carpet/commands/TickCommand.java +++ b/src/main/java/carpet/commands/TickCommand.java @@ -130,13 +130,13 @@ public class TickCommand private static int healthReport(ServerCommandSource source, int ticks) { - CarpetProfiler.prepare_tick_report(ticks); + CarpetProfiler.prepare_tick_report(source.getMinecraftServer(), ticks); return 1; } private static int healthEntities(ServerCommandSource source, int ticks) { - CarpetProfiler.prepare_entity_report(ticks); + CarpetProfiler.prepare_entity_report(source.getMinecraftServer(), ticks); return 1; } diff --git a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java index c65e2dc7..35fd5fe5 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_motdMixin.java @@ -7,12 +7,10 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import javax.annotation.Nullable; - @Mixin(MinecraftServer.class) public class MinecraftServer_motdMixin { - @Shadow @Nullable private String motd; + @Shadow private String motd; @Redirect(method = "run", at = @At( value = "FIELD", diff --git a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java index 11ee4a39..ab54cb4c 100644 --- a/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java +++ b/src/main/java/carpet/mixins/MinecraftServer_tickspeedMixin.java @@ -43,6 +43,8 @@ public abstract class MinecraftServer_tickspeedMixin @Shadow private volatile boolean loading; + CarpetProfiler.ProfilerToken currentSection; + // Cancel a while statement @Redirect(method = "run", at = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;running:Z")) private boolean cancelRunLoop(MinecraftServer server) @@ -61,6 +63,10 @@ public abstract class MinecraftServer_tickspeedMixin { //long long_1 = SystemUtil.getMeasuringTimeMs() - this.timeReference; //CM deciding on tick speed + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.start_tick_profiling(); + } long mspt = 0L; long long_1 = 0L; if (TickSpeed.time_warp_start_time != 0 && TickSpeed.continueWarp()) @@ -104,30 +110,6 @@ public abstract class MinecraftServer_tickspeedMixin } - @Inject(method = "tick", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/MinecraftServer;tickWorlds(Ljava/util/function/BooleanSupplier;)V", - shift = At.Shift.BEFORE - )) - private void startProfilerTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) - { - if (CarpetProfiler.tick_health_requested != 0L) - { - CarpetProfiler.start_tick_profiling(); - } - } - - @Inject( - method = "tick", - at = @At("TAIL") - ) - private void endTick(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - if (CarpetProfiler.tick_health_requested != 0L) - { - CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this); - } - } - @Inject(method = "tick", at = @At( value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;saveAllPlayerData()V", @@ -135,7 +117,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void startAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section(null, "Autosave"); + currentSection = CarpetProfiler.start_section(null, "Autosave", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tick", at = @At( @@ -145,7 +127,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void finishAutosave(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } @Inject(method = "tickWorlds", at = @At( @@ -155,7 +137,7 @@ public abstract class MinecraftServer_tickspeedMixin )) private void startNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section(null, "Network"); + currentSection = CarpetProfiler.start_section(null, "Network", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tickWorlds", at = @At( @@ -165,7 +147,25 @@ public abstract class MinecraftServer_tickspeedMixin )) private void finishNetwork(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); + } + + @Inject(method = "method_16208", at = @At("HEAD")) + private void startAsync(CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section(null, "Async Tasks", CarpetProfiler.TYPE.GENERAL); + } + @Inject(method = "method_16208", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/MinecraftServer;waitFor(Ljava/util/function/BooleanSupplier;)V", + shift = At.Shift.BEFORE + )) + private void stopAsync(CallbackInfo ci) + { + if (CarpetProfiler.tick_health_requested != 0L) + { + CarpetProfiler.end_tick_profiling((MinecraftServer) (Object)this, currentSection); + } } diff --git a/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java new file mode 100644 index 00000000..e8987d3e --- /dev/null +++ b/src/main/java/carpet/mixins/ServerChunkManager_tickMixin.java @@ -0,0 +1,64 @@ +package carpet.mixins; + +import carpet.utils.CarpetProfiler; +import net.minecraft.server.world.ServerChunkManager; +import net.minecraft.server.world.ServerWorld; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.function.BooleanSupplier; + +@Mixin(ServerChunkManager.class) +public abstract class ServerChunkManager_tickMixin +{ + @Shadow @Final private ServerWorld world; + CarpetProfiler.ProfilerToken currentSection; + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=purge" + )) + private void startTicketSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section(world, "Ticket Manager", CarpetProfiler.TYPE.GENERAL); + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=chunks" + )) + private void stopTicketStartSpawningSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section(world, "Spawning and Random Ticks", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At( + value = "CONSTANT", + args = "stringValue=unload" + )) + private void stopSpawningStartUnloadSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section(world, "Unloading", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At("TAIL")) + private void stopUnloadSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + } + } +} diff --git a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java index ab3ec193..8aadaacf 100644 --- a/src/main/java/carpet/mixins/ServerWorld_tickMixin.java +++ b/src/main/java/carpet/mixins/ServerWorld_tickMixin.java @@ -13,20 +13,83 @@ import java.util.function.BooleanSupplier; @Mixin(ServerWorld.class) public class ServerWorld_tickMixin { - CarpetProfiler.ProfilerToken entityToken; + CarpetProfiler.ProfilerToken currentSection; + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=world border" + )) + private void startWeatherSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + currentSection = CarpetProfiler.start_section((World)(Object)this, "Environment", CarpetProfiler.TYPE.GENERAL); + } + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=world border" + )) + private void stopWeatherStartChunkSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + // we go deeper here + } + } + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=tickPending" + )) + private void stopChunkStartBlockSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + // out of chunk + currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=village" + )) + private void stopBlockStartVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Village", CarpetProfiler.TYPE.GENERAL); + } + } + + @Inject(method = "tick", at = @At( + value = "CONSTANT", + args = "stringValue=tickPending" + )) + private void stopVillageStartBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + { + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL); + } + } @Inject(method = "tick", at = @At( value = "CONSTANT", args = "stringValue=entities" )) - private void startEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) + private void stopBlockAgainStartEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.start_section((World)(Object)this, "Entities"); + if (currentSection != null) + { + CarpetProfiler.end_current_section(currentSection); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Entities", CarpetProfiler.TYPE.GENERAL); + } } @Inject(method = "tick", at = @At("TAIL")) private void endEntitySection(BooleanSupplier booleanSupplier_1, CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } } diff --git a/src/main/java/carpet/mixins/World_tickMixin.java b/src/main/java/carpet/mixins/World_tickMixin.java index 3285f7cf..ea22dfce 100644 --- a/src/main/java/carpet/mixins/World_tickMixin.java +++ b/src/main/java/carpet/mixins/World_tickMixin.java @@ -2,6 +2,7 @@ package carpet.mixins; import carpet.utils.CarpetProfiler; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Entity; import net.minecraft.util.profiler.Profiler; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; @@ -11,20 +12,22 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Iterator; +import java.util.function.Consumer; @Mixin(World.class) public abstract class World_tickMixin { - CarpetProfiler.ProfilerToken beToken; + CarpetProfiler.ProfilerToken currentSection; + CarpetProfiler.ProfilerToken entitySection; @Inject(method = "tickBlockEntities", at = @At("HEAD")) private void startBlockEntities(CallbackInfo ci) { - CarpetProfiler.start_section((World) (Object) this, "Tile Entities"); + currentSection = CarpetProfiler.start_section((World) (Object) this, "Tile Entities", CarpetProfiler.TYPE.GENERAL); } @Inject(method = "tickBlockEntities", at = @At("TAIL")) private void endBlockEntities(CallbackInfo ci) { - CarpetProfiler.end_current_section(); + CarpetProfiler.end_current_section(currentSection); } @Inject(method = "tickBlockEntities", locals = LocalCapture.CAPTURE_FAILHARD, at = @At( @@ -33,9 +36,9 @@ public abstract class World_tickMixin shift = At.Shift.BEFORE, ordinal = 0 )) - private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, int int_1, BlockEntity blockEntity_2) + private void startTileEntitySection(CallbackInfo ci, Profiler profiler_1, Iterator i, BlockEntity blockEntity_2) { - beToken = CarpetProfiler.start_tileentity_section((World)(Object)this, blockEntity_2); + entitySection = CarpetProfiler.start_entity_section((World)(Object)this, blockEntity_2, CarpetProfiler.TYPE.TILEENTITY); } @Inject(method = "tickBlockEntities", at = @At( @@ -46,8 +49,18 @@ public abstract class World_tickMixin )) private void endTileEntitySection(CallbackInfo ci) { - CarpetProfiler.end_current_entity_section(beToken); - beToken = null; + CarpetProfiler.end_current_entity_section(entitySection); + } + + @Inject(method = "tickEntity", at = @At("HEAD")) + private void startEntity(Consumer call, Entity e, CallbackInfo ci) + { + entitySection = CarpetProfiler.start_entity_section((World) (Object) this, e, CarpetProfiler.TYPE.ENTITY); + } + + @Inject(method = "tickEntity", at = @At("TAIL")) + private void endEntity(Consumer call, Entity e, CallbackInfo ci) { + CarpetProfiler.end_current_entity_section(entitySection); } diff --git a/src/main/java/carpet/utils/CarpetProfiler.java b/src/main/java/carpet/utils/CarpetProfiler.java index 97c14584..fd1e3ac9 100644 --- a/src/main/java/carpet/utils/CarpetProfiler.java +++ b/src/main/java/carpet/utils/CarpetProfiler.java @@ -4,7 +4,6 @@ import carpet.CarpetSettings; import net.minecraft.entity.Entity; import net.minecraft.server.MinecraftServer; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; @@ -18,196 +17,153 @@ public class CarpetProfiler private static final HashMap time_repo = new HashMap<>(); public static int tick_health_requested = 0; private static int tick_health_elapsed = 0; - private static int test_type = 0; //1 for ticks, 2 for entities; - private static String current_section = null; - private static long current_section_start = 0; + private static TYPE test_type = TYPE.NONE; //1 for ticks, 2 for entities; private static long current_tick_start = 0; - private static String [] GENERAL_SECTIONS = {"Network", "Autosave"}; - private static String [] DIMENSIONS = {"Overworld","The End","The Nether"}; - private static String [] SECTIONS = {"Spawning","Blocks","Entities","Tile Entities","Entities(client)","Tile Entities(client)","Villages"}; + private static String[] GENERAL_SECTIONS = {"Network", "Autosave", "Async Tasks"}; + private static String[] DIMENSIONS = {"overworld", "the_end", "the_nether"}; + private static String[] SECTIONS = { + "Spawning and Random Ticks", "Ticket Manager","Unloading", + "Blocks", "Entities", "Tile Entities", + "Entities (Client)", "Tile Entities (Client)", + "Village", "Environment"}; - public static void prepare_tick_report(int ticks) + public enum TYPE + { + NONE, + GENERAL, + ENTITY, + TILEENTITY + } + + public static class ProfilerToken + { + public TYPE type; + public Object section; + public long start; + public World world; + + public ProfilerToken(TYPE type, Object section, World world, long start) + { + this.type = type; + this.section = section; + this.start = start; + this.world = world; + } + } + + private static String getWorldString(World world) + { + return world.getDimension().getType().toString().replaceFirst("minecraft:", "") + (world.isClient ? "(Client)" : ""); + } + + private static String getSectionString(World world, String section) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + section, + world.isClient ? " (Client)" : ""); + } + + private static String getEntityString(World world, Entity e) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:", ""), + world.isClient ? " (Client)" : ""); + } + + private static String getTEntityString(World world, BlockEntity be) + { + return String.format("%s.%s%s", + world.getDimension().getType().toString().replaceFirst("minecraft:", ""), + Registry.BLOCK_ENTITY.getId(be.getType()).toString().replaceFirst("minecraft:", ""), + world.isClient ? " (Client)" : ""); + } + + public static void prepare_tick_report(MinecraftServer server, int ticks) { //maybe add so it only spams the sending player, but honestly - all may want to see it time_repo.clear(); - test_type = 1; - time_repo.put("tick",0L); - time_repo.put("Network",0L); - time_repo.put("Autosave",0L); - for (String section: GENERAL_SECTIONS) + test_type = TYPE.GENERAL; + time_repo.put("tick", 0L); + time_repo.put("Network", 0L); + time_repo.put("Autosave", 0L); + for (String section : GENERAL_SECTIONS) { - time_repo.put(section,0L); + time_repo.put(section, 0L); } - for (String level: DIMENSIONS) + for (String level : DIMENSIONS) { - for (String section: SECTIONS) + for (String section : SECTIONS) { - time_repo.put(level+"."+section,0L); + time_repo.put(level + "." + section, 0L); } } tick_health_elapsed = ticks; tick_health_requested = ticks; current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - } - public static void start_section(World world, String name) + public static void prepare_entity_report(MinecraftServer server, int ticks) { - if (tick_health_requested == 0L || test_type != 1) - { + //maybe add so it only spams the sending player, but honestly - all may want to see it + time_repo.clear(); + time_repo.put("tick", 0L); + test_type = TYPE.ENTITY; + tick_health_elapsed = ticks; + tick_health_requested = ticks; + current_tick_start = 0L; + } + + public static ProfilerToken start_section(World world, String name, TYPE type) + { + if (tick_health_requested == 0L || test_type != TYPE.GENERAL || current_tick_start == 0) + return null; + return new ProfilerToken(type, name, world, System.nanoTime()); + } + + public static ProfilerToken start_entity_section(World world, Object e, TYPE type) + { + if (tick_health_requested == 0L || test_type != TYPE.ENTITY || current_tick_start == 0) + return null; + return new ProfilerToken(type, e, world, System.nanoTime()); + } + + public static void end_current_section(ProfilerToken tok) + { + if (tick_health_requested == 0L || test_type != TYPE.GENERAL || current_tick_start == 0) return; - } - if (current_tick_start == 0L) - { - return; - } - if (current_section != null) - { - end_current_section(); - } - String key = name; - if (world != null) - { - key = world.getDimension().getType().getSuffix()+"."+name; - } - current_section = key; - current_section_start = System.nanoTime(); - } - - - public static class ProfilerToken - { - public String section; - public long start; - public ProfilerToken(String name, long start) - { - this.section = name; - this.start = start; - } - } - - public static ProfilerToken start_section_concurrent(World world, String name, boolean isRemote) - { - if (tick_health_requested == 0L || test_type != 1) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - - String key = name; - if (world != null) - { - key = world.getDimension().getType().getSuffix()+"."+name; - } - if (isRemote) key += "(client)"; - long time = System.nanoTime(); - return new ProfilerToken(key, time); - } - - public static ProfilerToken start_entity_section(World world, Entity e) - { - if (tick_health_requested == 0L || test_type != 2) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - String section = world.getDimension().getType().getSuffix()+"."+ Registry.ENTITY_TYPE.getId(e.getType()).toString().replaceFirst("minecraft:",""); - if (e.getEntityWorld().isClient) - section += "(client)"; - long section_start = System.nanoTime(); - return new ProfilerToken(section, section_start); - } - - public static ProfilerToken start_tileentity_section(World world, BlockEntity e) - { - if (tick_health_requested == 0L || test_type != 2) - { - return null; - } - if (current_tick_start == 0L) - { - return null; - } - String section = world.getDimension().getType().getSuffix()+"."+ BlockEntityType.getId(e.getType()).toString().replaceFirst("minecraft:",""); - if (e.getWorld() == null) - section += "??"; - else if (e.getWorld().isClient) - section += "(client)"; - long section_start = System.nanoTime(); - return new ProfilerToken(section, section_start); - } - - public static void end_current_section() - { - if (tick_health_requested == 0L || test_type != 1) - { - return; - } long end_time = System.nanoTime(); - if (current_tick_start == 0L) + if (tok.type == TYPE.GENERAL) { - return; + String current_section = (tok.world == null) ? (String) tok.section : + getSectionString(tok.world, (String)tok.section); + if (time_repo.get(current_section) == null) + { + CarpetSettings.LOG.error("Current section: "+current_section); + } + else + time_repo.put(current_section, time_repo.get(current_section) + end_time - tok.start); } - if (current_section == null) - { - CarpetSettings.LOG.error("finishing section that hasn't started"); - return; - } - //CarpetSettings.LOG.error("finishing section "+current_section); - time_repo.put(current_section,time_repo.get(current_section)+end_time-current_section_start); - current_section = null; - current_section_start = 0; - } - - public static void end_current_section_concurrent(ProfilerToken tok) - { - if (tick_health_requested == 0L || test_type != 1) - { - return; - } - long end_time = System.nanoTime(); - if (current_tick_start == 0L) - { - return; - } - if (tok == null) - { - CarpetSettings.LOG.error("finishing section that hasn't started"); - return; - } - //CarpetSettings.LOG.error("finishing section "+current_section); - time_repo.put(tok.section,time_repo.get(tok.section)+end_time-tok.start); } public static void end_current_entity_section(ProfilerToken tok) { - if (tick_health_requested == 0L || test_type != 2) - { + if (tick_health_requested == 0L || test_type != TYPE.ENTITY || current_tick_start == 0) return; - } long end_time = System.nanoTime(); - if (current_tick_start == 0L) - { + String section; + if (tok.type == TYPE.ENTITY) + section = getEntityString(tok.world, (Entity) tok.section); + else if (tok.type == TYPE.TILEENTITY) + section = getTEntityString(tok.world, (BlockEntity) tok.section); + else return; - } - if (tok == null) - { - CarpetSettings.LOG.error("finishing entity/TE section that hasn't started"); - return; - } - String time_section = "t."+tok.section; - String count_section = "c."+tok.section; - time_repo.put(time_section,time_repo.getOrDefault(time_section,0L)+end_time-tok.start); - time_repo.put(count_section,time_repo.getOrDefault(count_section,0L)+1); + String time_section = "t." + section; + String count_section = "c." + section; + time_repo.put(time_section, time_repo.getOrDefault(time_section, 0L) + end_time - tok.start); + time_repo.put(count_section, time_repo.getOrDefault(count_section, 0L) + 1); } public static void start_tick_profiling() @@ -215,15 +171,14 @@ public class CarpetProfiler current_tick_start = System.nanoTime(); } - public static void end_tick_profiling(MinecraftServer server) + public static void end_tick_profiling(MinecraftServer server, ProfilerToken postTasks) { if (current_tick_start == 0L) - { return; - } - time_repo.put("tick",time_repo.get("tick")+System.nanoTime()-current_tick_start); - tick_health_elapsed --; - //CarpetSettings.LOG.error("tick count current at "+time_repo.get("tick")); + if (postTasks != null) + end_current_section(postTasks); + time_repo.put("tick", time_repo.get("tick") + System.nanoTime() - current_tick_start); + tick_health_elapsed--; if (tick_health_elapsed <= 0) { finalize_tick_report(server); @@ -232,41 +187,35 @@ public class CarpetProfiler public static void finalize_tick_report(MinecraftServer server) { - if (test_type == 1) - { + if (test_type == TYPE.GENERAL) finalize_tick_report_for_time(server); - } - if (test_type == 2) - { + if (test_type == TYPE.ENTITY) finalize_tick_report_for_entities(server); - } cleanup_tick_report(); } public static void cleanup_tick_report() { time_repo.clear(); - time_repo.put("tick",0L); - test_type = 0; + time_repo.put("tick", 0L); + test_type = TYPE.NONE; tick_health_elapsed = 0; tick_health_requested = 0; current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - } public static void finalize_tick_report_for_time(MinecraftServer server) { //print stats long total_tick_time = time_repo.get("tick"); - double divider = 1.0D/tick_health_requested/1000000; - Messenger.print_server_message(server, String.format("Average tick time: %.3fms",divider*total_tick_time)); + double divider = 1.0D / tick_health_requested / 1000000; + Messenger.print_server_message(server, ""); + Messenger.print_server_message(server, String.format("Average tick time: %.3fms", divider * total_tick_time)); long accumulated = 0L; - for (String section: GENERAL_SECTIONS) + for (String section : GENERAL_SECTIONS) { - double amount = divider*time_repo.get(section); + double amount = divider * time_repo.get(section); if (amount > 0.01) { accumulated += time_repo.get(section); @@ -274,12 +223,12 @@ public class CarpetProfiler } } - for (String dimension: DIMENSIONS) + for (String dimension : DIMENSIONS) { boolean hasSomethin = false; - for (String section: SECTIONS) + for (String section : SECTIONS) { - double amount = divider*time_repo.get(dimension+"."+section); + double amount = divider * time_repo.get(dimension + "." + section); if (amount > 0.01) { hasSomethin = true; @@ -290,35 +239,36 @@ public class CarpetProfiler { continue; } - Messenger.print_server_message(server, dimension+":"); - for (String section: SECTIONS) + Messenger.print_server_message(server, dimension + ":"); + for (String section : SECTIONS) { - double amount = divider*time_repo.get(dimension+"."+section); + double amount = divider * time_repo.get(dimension + "." + section); if (amount > 0.01) { if (!(section.endsWith("(client)"))) - accumulated += time_repo.get(dimension+"."+section); + accumulated += time_repo.get(dimension + "." + section); Messenger.print_server_message(server, String.format(" - %s: %.3fms", section, amount)); } } } - long rest = total_tick_time-accumulated; + long rest = total_tick_time - accumulated; - Messenger.print_server_message(server, String.format("The Rest, whatever that might be: %.3fms",divider*rest)); + Messenger.print_server_message(server, String.format("The Rest, whatever that might be: %.3fms", divider * rest)); } public static void finalize_tick_report_for_entities(MinecraftServer server) { //print stats long total_tick_time = time_repo.get("tick"); - double divider = 1.0D/tick_health_requested/1000000; - double divider_1 = 1.0D/(tick_health_requested-1)/1000000; - Messenger.print_server_message(server, String.format("Average tick time: %.3fms",divider*total_tick_time)); + double divider = 1.0D / tick_health_requested / 1000000; + double divider_1 = 1.0D / (tick_health_requested - 1) / 1000000; + Messenger.print_server_message(server, ""); + Messenger.print_server_message(server, String.format("Average tick time: %.3fms", divider * total_tick_time)); time_repo.remove("tick"); Messenger.print_server_message(server, "Top 10 counts:"); int total = 0; - for ( Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()) ) + for (Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList())) { if (entry.getKey().startsWith("t.")) { @@ -332,12 +282,12 @@ public class CarpetProfiler String[] parts = entry.getKey().split("\\."); String dim = parts[1]; String name = parts[2]; - int penalty = name.endsWith("(client)") ? 1 :0; - Messenger.print_server_message(server, String.format(" - %s in %s: %.3f",name, dim, 1.0D*entry.getValue()/(tick_health_requested-penalty))); + int penalty = name.endsWith("(client)") ? 1 : 0; + Messenger.print_server_message(server, String.format(" - %s in %s: %.3f", name, dim, 1.0D * entry.getValue() / (tick_health_requested - penalty))); } Messenger.print_server_message(server, "Top 10 grossing:"); total = 0; - for ( Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()) ) + for (Map.Entry entry : time_repo.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList())) { if (entry.getKey().startsWith("c.")) { @@ -351,23 +301,8 @@ public class CarpetProfiler String[] parts = entry.getKey().split("\\."); String dim = parts[1]; String name = parts[2]; - double applicableDivider = name.endsWith("(client)") ? divider :divider_1; - Messenger.print_server_message(server, String.format(" - %s in %s: %.3fms",name, dim, applicableDivider*entry.getValue())); + double applicableDivider = name.endsWith("(client)") ? divider : divider_1; + Messenger.print_server_message(server, String.format(" - %s in %s: %.3fms", name, dim, applicableDivider * entry.getValue())); } - } - - public static void prepare_entity_report(int ticks) - { - //maybe add so it only spams the sending player, but honestly - all may want to see it - time_repo.clear(); - time_repo.put("tick",0L); - test_type = 2; - tick_health_elapsed = ticks; - tick_health_requested = ticks; - current_tick_start = 0L; - current_section_start = 0L; - current_section = null; - - } -} +} \ No newline at end of file diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index e1dc2d76..571fc132 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -5,8 +5,12 @@ "mixins": [ "CommandManagerMixin", "MinecraftServer_coreMixin", + "MinecraftServer_tickspeedMixin", "World_tickMixin", + "ServerWorld_tickMixin", + "ServerChunkManager_tickMixin", + "MinecraftServer_motdMixin", "ServerPlayNetworkHandlerMixin", "MinecraftServer_scarpetMixin",