Better handle async timings

This commit is contained in:
Sotr
2018-06-14 19:33:08 +08:00
parent dc30e8c8d5
commit 3e38351ce7

View File

@@ -7,20 +7,41 @@ import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
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.CallbackInfoReturnable;
import co.aikar.timings.Timing;
import io.akarin.api.internal.Akari;
import io.akarin.server.core.AkarinGlobalConfig;
@Mixin(targets = "co.aikar.timings.TimingHandler", remap = false)
public class MixinTimingHandler {
public abstract class MixinTimingHandler {
@Shadow @Final String name;
@Shadow private boolean enabled;
@Shadow private volatile long start;
@Shadow private volatile int timingDepth;
@Shadow abstract void addDiff(long diff);
@Shadow public abstract Timing startTiming();
@Overwrite
public Timing startTimingIfSync() {
if (Akari.isPrimaryThread()) { // Use non-mock method
startTiming();
}
return (Timing) this;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Inject(method = "startTiming", at = @At("HEAD"), cancellable = true)
public void onStartTiming(CallbackInfoReturnable ci) {
if (Akari.silentTiming || !Akari.isPrimaryThread()) ci.setReturnValue(this); // Avoid modify any field
}
@Overwrite
public void stopTimingIfSync() {
if (Akari.isPrimaryThread()) { // Akarin
if (Akari.isPrimaryThread()) { // Use non-mock method
stopTiming(true); // Avoid twice thread check
}
}
@@ -30,23 +51,17 @@ public class MixinTimingHandler {
stopTiming(false);
}
@Shadow void addDiff(long diff) {}
public void stopTiming(boolean sync) {
if (enabled && --timingDepth == 0 && start != 0) {
if (Akari.silentTiming) { // It must be off-main thread now
start = 0;
return;
} else {
if (!sync && !Akari.isPrimaryThread()) { // Akarin
if (AkarinGlobalConfig.silentAsyncTimings) {
Bukkit.getLogger().log(Level.SEVERE, "stopTiming called async for " + name);
new Throwable().printStackTrace();
}
start = 0;
return;
}
}
public void stopTiming(boolean alreadySync) {
if (!enabled || Akari.silentTiming) return;
if (!alreadySync && !Akari.isPrimaryThread()) {
if (AkarinGlobalConfig.silentAsyncTimings) return;
Bukkit.getLogger().log(Level.SEVERE, "stopTiming called async for " + name);
new Throwable().printStackTrace();
}
// Main thread ensured
if (--timingDepth == 0 && start != 0) {
addDiff(System.nanoTime() - start);
start = 0;
}