feat: detect hitches in framework update, draw and gamenetwork

This commit is contained in:
goat 2023-02-17 21:02:49 +01:00
parent 268ddfbea0
commit 44dc127101
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
4 changed files with 109 additions and 57 deletions

View file

@ -9,7 +9,6 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Game.Gui;
using Dalamud.Game.Gui.Toast;
using Dalamud.Game.Network;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
@ -29,6 +28,7 @@ public sealed class Framework : IDisposable, IServiceType
private static Stopwatch statsStopwatch = new();
private readonly Stopwatch updateStopwatch = new();
private readonly HitchDetector hitchDetector = new("FrameworkUpdate", 20);
private readonly Hook<OnUpdateDetour> updateHook;
private readonly Hook<OnRealDestroyDelegate> destroyHook;
@ -368,18 +368,18 @@ public sealed class Framework : IDisposable, IServiceType
ThreadSafety.MarkMainThread();
this.hitchDetector.Start();
try
{
var chatGui = Service<ChatGui>.GetNullable();
var toastGui = Service<ToastGui>.GetNullable();
var gameNetwork = Service<GameNetwork>.GetNullable();
var config = Service<DalamudConfiguration>.GetNullable();
if (chatGui == null || toastGui == null || gameNetwork == null)
if (chatGui == null || toastGui == null)
goto original;
chatGui.UpdateQueue();
toastGui.UpdateQueue();
gameNetwork.UpdateQueue();
config?.Update();
}
@ -397,7 +397,31 @@ public sealed class Framework : IDisposable, IServiceType
this.LastUpdate = DateTime.Now;
this.LastUpdateUTC = DateTime.UtcNow;
this.RunPendingTickTasks();
void AddToStats(string key, double ms)
{
if (!StatsHistory.ContainsKey(key))
StatsHistory.Add(key, new List<double>());
StatsHistory[key].Add(ms);
if (StatsHistory[key].Count > 1000)
{
StatsHistory[key].RemoveRange(0, StatsHistory[key].Count - 1000);
}
}
if (StatsEnabled)
{
statsStopwatch.Restart();
this.RunPendingTickTasks();
statsStopwatch.Stop();
AddToStats(nameof(this.RunPendingTickTasks), statsStopwatch.Elapsed.TotalMilliseconds);
}
else
{
this.RunPendingTickTasks();
}
if (StatsEnabled && this.Update != null)
{
@ -424,20 +448,15 @@ public sealed class Framework : IDisposable, IServiceType
if (notUpdated.Contains(key))
notUpdated.Remove(key);
if (!StatsHistory.ContainsKey(key))
StatsHistory.Add(key, new List<double>());
StatsHistory[key].Add(statsStopwatch.Elapsed.TotalMilliseconds);
if (StatsHistory[key].Count > 1000)
{
StatsHistory[key].RemoveRange(0, StatsHistory[key].Count - 1000);
}
AddToStats(key, statsStopwatch.Elapsed.TotalMilliseconds);
}
// Cleanup handlers that are no longer being called
foreach (var key in notUpdated)
{
if (key == nameof(this.RunPendingTickTasks))
continue;
if (StatsHistory[key].Count > 0)
{
StatsHistory[key].RemoveAt(0);
@ -454,6 +473,8 @@ public sealed class Framework : IDisposable, IServiceType
}
}
this.hitchDetector.Stop();
original:
return this.updateHook.OriginalDisposeSafe(framework);
}