mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-15 14:13:56 +01:00
Improvements to Timings
With 1.13, the idea of accessing chunks async is going to have to be supported with the push towards thread safe chunk access mojang has done. This commit changes timings to always thread check at start and stop timings and only mutate state on main thread. This makes startTimingIfSync pointless, but I'm just going to leave it as is. Timings will no longer complain when used async, it just will not do anything. Further concurrency issues have been addressed with creating timings handlers that may of overall been an issue for any handler that might of been created async (happened even for things that only timed sync) with that, the 'protected' concept of handlers has been removed, and 'plugin' vs 'safe' handlers are now the same. Got rid of some guava functions in favor of java 8 real stuff now too.
This commit is contained in:
parent
8eef3b43f3
commit
a8f31a2704
1 changed files with 39 additions and 51 deletions
|
@ -6,7 +6,7 @@ Subject: [PATCH] Timings v2
|
|||
|
||||
diff --git a/src/main/java/co/aikar/timings/FullServerTickHandler.java b/src/main/java/co/aikar/timings/FullServerTickHandler.java
|
||||
new file mode 100644
|
||||
index 000000000..4d8b633ed
|
||||
index 000000000..98079dc0c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/FullServerTickHandler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
|
@ -15,7 +15,7 @@ index 000000000..4d8b633ed
|
|||
+import static co.aikar.timings.TimingsManager.*;
|
||||
+
|
||||
+public class FullServerTickHandler extends TimingHandler {
|
||||
+ private static final TimingIdentifier IDENTITY = new TimingIdentifier("Minecraft", "Full Server Tick", null, false);
|
||||
+ private static final TimingIdentifier IDENTITY = new TimingIdentifier("Minecraft", "Full Server Tick", null);
|
||||
+ final TimingData minuteData;
|
||||
+ double avgFreeMemory = -1D;
|
||||
+ double avgUsedMemory = -1D;
|
||||
|
@ -456,7 +456,7 @@ index 000000000..f222d6b7d
|
|||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingHandler.java b/src/main/java/co/aikar/timings/TimingHandler.java
|
||||
new file mode 100644
|
||||
index 000000000..916b6f9d6
|
||||
index 000000000..521c985e6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/TimingHandler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
|
@ -489,12 +489,13 @@ index 000000000..916b6f9d6
|
|||
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
+import org.bukkit.Bukkit;
|
||||
+
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+import java.util.logging.Level;
|
||||
+
|
||||
+class TimingHandler implements Timing {
|
||||
+
|
||||
+ private static int idPool = 1;
|
||||
+ final int id = idPool++;
|
||||
+ private static AtomicInteger idPool = new AtomicInteger(1);
|
||||
+ final int id = idPool.getAndIncrement();
|
||||
+
|
||||
+ final String name;
|
||||
+ private final boolean verbose;
|
||||
|
@ -546,21 +547,17 @@ index 000000000..916b6f9d6
|
|||
+
|
||||
+ @Override
|
||||
+ public Timing startTimingIfSync() {
|
||||
+ if (Bukkit.isPrimaryThread()) {
|
||||
+ startTiming();
|
||||
+ }
|
||||
+ startTiming();
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void stopTimingIfSync() {
|
||||
+ if (Bukkit.isPrimaryThread()) {
|
||||
+ stopTiming();
|
||||
+ }
|
||||
+ stopTiming();
|
||||
+ }
|
||||
+
|
||||
+ public Timing startTiming() {
|
||||
+ if (enabled && ++timingDepth == 1) {
|
||||
+ if (enabled && Bukkit.isPrimaryThread() && ++timingDepth == 1) {
|
||||
+ start = System.nanoTime();
|
||||
+ parent = TimingsManager.CURRENT;
|
||||
+ TimingsManager.CURRENT = this;
|
||||
|
@ -569,13 +566,7 @@ index 000000000..916b6f9d6
|
|||
+ }
|
||||
+
|
||||
+ public void stopTiming() {
|
||||
+ if (enabled && --timingDepth == 0 && start != 0) {
|
||||
+ if (!Bukkit.isPrimaryThread()) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "stopTiming called async for " + name);
|
||||
+ new Throwable().printStackTrace();
|
||||
+ start = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (enabled && timingDepth > 0 && Bukkit.isPrimaryThread() && --timingDepth == 0 && start != 0) {
|
||||
+ addDiff(System.nanoTime() - start);
|
||||
+ start = 0;
|
||||
+ }
|
||||
|
@ -1090,7 +1081,7 @@ index 000000000..0e114eb32
|
|||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingIdentifier.java b/src/main/java/co/aikar/timings/TimingIdentifier.java
|
||||
new file mode 100644
|
||||
index 000000000..623dda49c
|
||||
index 000000000..63b4f318a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/TimingIdentifier.java
|
||||
@@ -0,0 +0,0 @@
|
||||
|
@ -1119,12 +1110,12 @@ index 000000000..623dda49c
|
|||
+ */
|
||||
+package co.aikar.timings;
|
||||
+
|
||||
+import com.google.common.base.Function;
|
||||
+import co.aikar.util.LoadingMap;
|
||||
+import co.aikar.util.MRUMapCache;
|
||||
+
|
||||
+import java.util.ArrayDeque;
|
||||
+import java.util.Map;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+
|
||||
+/**
|
||||
+ * <p>Used as a basis for fast HashMap key comparisons for the Timing Map.</p>
|
||||
|
@ -1136,25 +1127,18 @@ index 000000000..623dda49c
|
|||
+ * Holds all groups. Autoloads on request for a group by name.
|
||||
+ */
|
||||
+ static final Map<String, TimingGroup> GROUP_MAP = MRUMapCache.of(
|
||||
+ LoadingMap.newIdentityHashMap(new Function<String, TimingGroup>() {
|
||||
+ @Override
|
||||
+ public TimingGroup apply(String group) {
|
||||
+ return new TimingGroup(group);
|
||||
+ }
|
||||
+ }, 64)
|
||||
+ LoadingMap.newIdentityHashMap(TimingGroup::new, 64)
|
||||
+ );
|
||||
+ static final TimingGroup DEFAULT_GROUP = getGroup("Minecraft");
|
||||
+ private static final TimingGroup DEFAULT_GROUP = getGroup("Minecraft");
|
||||
+ final String group;
|
||||
+ final String name;
|
||||
+ final TimingHandler groupHandler;
|
||||
+ final boolean protect;
|
||||
+ private final int hashCode;
|
||||
+
|
||||
+ TimingIdentifier(String group, String name, Timing groupHandler, boolean protect) {
|
||||
+ TimingIdentifier(String group, String name, Timing groupHandler) {
|
||||
+ this.group = group != null ? group.intern() : DEFAULT_GROUP.name;
|
||||
+ this.name = name.intern();
|
||||
+ this.groupHandler = groupHandler != null ? groupHandler.getTimingHandler() : null;
|
||||
+ this.protect = protect;
|
||||
+ this.hashCode = (31 * this.group.hashCode()) + this.name.hashCode();
|
||||
+ }
|
||||
+
|
||||
|
@ -1185,8 +1169,8 @@ index 000000000..623dda49c
|
|||
+
|
||||
+ static class TimingGroup {
|
||||
+
|
||||
+ private static int idPool = 1;
|
||||
+ final int id = idPool++;
|
||||
+ private static AtomicInteger idPool = new AtomicInteger(1);
|
||||
+ final int id = idPool.getAndIncrement();
|
||||
+
|
||||
+ final String name;
|
||||
+ ArrayDeque<TimingHandler> handlers = new ArrayDeque<TimingHandler>(64);
|
||||
|
@ -1194,11 +1178,24 @@ index 000000000..623dda49c
|
|||
+ private TimingGroup(String name) {
|
||||
+ this.name = name;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (o == null || getClass() != o.getClass()) return false;
|
||||
+ TimingGroup that = (TimingGroup) o;
|
||||
+ return id == that.id;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return id;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
|
||||
new file mode 100644
|
||||
index 000000000..32e4bb1e2
|
||||
index 000000000..f907649ba
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/Timings.java
|
||||
@@ -0,0 +0,0 @@
|
||||
|
@ -1278,7 +1275,7 @@ index 000000000..32e4bb1e2
|
|||
+ */
|
||||
+ public static Timing of(Plugin plugin, String name, Timing groupHandler) {
|
||||
+ Preconditions.checkNotNull(plugin, "Plugin can not be null");
|
||||
+ return TimingsManager.getHandler(plugin.getName(), name, groupHandler, true);
|
||||
+ return TimingsManager.getHandler(plugin.getName(), name, groupHandler);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
|
@ -1310,7 +1307,7 @@ index 000000000..32e4bb1e2
|
|||
+ */
|
||||
+ public static Timing ofStart(Plugin plugin, String name, Timing groupHandler) {
|
||||
+ Timing timing = of(plugin, name, groupHandler);
|
||||
+ timing.startTimingIfSync();
|
||||
+ timing.startTiming();
|
||||
+ return timing;
|
||||
+ }
|
||||
+
|
||||
|
@ -1483,7 +1480,7 @@ index 000000000..32e4bb1e2
|
|||
+ }
|
||||
+
|
||||
+ static TimingHandler ofSafe(String groupName, String name, Timing groupHandler) {
|
||||
+ return TimingsManager.getHandler(groupName, name, groupHandler, false);
|
||||
+ return TimingsManager.getHandler(groupName, name, groupHandler);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java
|
||||
|
@ -1961,7 +1958,7 @@ index 000000000..df7f42595
|
|||
+}
|
||||
diff --git a/src/main/java/co/aikar/timings/TimingsManager.java b/src/main/java/co/aikar/timings/TimingsManager.java
|
||||
new file mode 100644
|
||||
index 000000000..58ed35e00
|
||||
index 000000000..e0f3e07fe
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/aikar/timings/TimingsManager.java
|
||||
@@ -0,0 +0,0 @@
|
||||
|
@ -1990,7 +1987,6 @@ index 000000000..58ed35e00
|
|||
+ */
|
||||
+package co.aikar.timings;
|
||||
+
|
||||
+import com.google.common.base.Function;
|
||||
+import com.google.common.collect.EvictingQueue;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.Server;
|
||||
|
@ -2010,16 +2006,8 @@ index 000000000..58ed35e00
|
|||
+public final class TimingsManager {
|
||||
+ static final Map<TimingIdentifier, TimingHandler> TIMING_MAP =
|
||||
+ Collections.synchronizedMap(LoadingMap.newHashMap(
|
||||
+ new Function<TimingIdentifier, TimingHandler>() {
|
||||
+ @Override
|
||||
+ public TimingHandler apply(TimingIdentifier id) {
|
||||
+ return (id.protect ?
|
||||
+ new UnsafeTimingHandler(id) :
|
||||
+ new TimingHandler(id)
|
||||
+ );
|
||||
+ }
|
||||
+ },
|
||||
+ 256, .5F
|
||||
+ TimingHandler::new,
|
||||
+ 4096, .5F
|
||||
+ ));
|
||||
+ public static final FullServerTickHandler FULL_SERVER_TICK = new FullServerTickHandler();
|
||||
+ public static final TimingHandler TIMINGS_TICK = Timings.ofSafe("Timings Tick", FULL_SERVER_TICK);
|
||||
|
@ -2108,8 +2096,8 @@ index 000000000..58ed35e00
|
|||
+ historyStart = System.currentTimeMillis();
|
||||
+ }
|
||||
+
|
||||
+ static TimingHandler getHandler(String group, String name, Timing parent, boolean protect) {
|
||||
+ return TIMING_MAP.get(new TimingIdentifier(group, name, parent, protect));
|
||||
+ static TimingHandler getHandler(String group, String name, Timing parent) {
|
||||
+ return TIMING_MAP.get(new TimingIdentifier(group, name, parent));
|
||||
+ }
|
||||
+
|
||||
+
|
||||
|
|
Loading…
Reference in a new issue