aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Debugger/Profiler/InternalProfile.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Debugger/Profiler/InternalProfile.cs')
-rw-r--r--Ryujinx.Debugger/Profiler/InternalProfile.cs223
1 files changed, 0 insertions, 223 deletions
diff --git a/Ryujinx.Debugger/Profiler/InternalProfile.cs b/Ryujinx.Debugger/Profiler/InternalProfile.cs
deleted file mode 100644
index 0bda9e04..00000000
--- a/Ryujinx.Debugger/Profiler/InternalProfile.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-using Ryujinx.Common;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Debugger.Profiler
-{
- public class InternalProfile
- {
- private struct TimerQueueValue
- {
- public ProfileConfig Config;
- public long Time;
- public bool IsBegin;
- }
-
- internal Dictionary<ProfileConfig, TimingInfo> Timers { get; set; }
-
- private readonly object _timerQueueClearLock = new object();
- private ConcurrentQueue<TimerQueueValue> _timerQueue;
-
- private int _sessionCounter = 0;
-
- // Cleanup thread
- private readonly Thread _cleanupThread;
- private bool _cleanupRunning;
- private readonly long _history;
- private long _preserve;
-
- // Timing flags
- private TimingFlag[] _timingFlags;
- private long[] _timingFlagAverages;
- private long[] _timingFlagLast;
- private long[] _timingFlagLastDelta;
- private int _timingFlagCount;
- private int _timingFlagIndex;
-
- private int _maxFlags;
-
- private Action<TimingFlag> _timingFlagCallback;
-
- public InternalProfile(long history, int maxFlags)
- {
- _maxFlags = maxFlags;
- Timers = new Dictionary<ProfileConfig, TimingInfo>();
- _timingFlags = new TimingFlag[_maxFlags];
- _timingFlagAverages = new long[(int)TimingFlagType.Count];
- _timingFlagLast = new long[(int)TimingFlagType.Count];
- _timingFlagLastDelta = new long[(int)TimingFlagType.Count];
- _timerQueue = new ConcurrentQueue<TimerQueueValue>();
- _history = history;
- _cleanupRunning = true;
-
- // Create cleanup thread.
- _cleanupThread = new Thread(CleanupLoop)
- {
- Name = "Profiler.CleanupThread"
- };
- _cleanupThread.Start();
- }
-
- private void CleanupLoop()
- {
- bool queueCleared = false;
-
- while (_cleanupRunning)
- {
- // Ensure we only ever have 1 instance modifying timers or timerQueue
- if (Monitor.TryEnter(_timerQueueClearLock))
- {
- queueCleared = ClearTimerQueue();
-
- // Calculate before foreach to mitigate redundant calculations
- long cleanupBefore = PerformanceCounter.ElapsedTicks - _history;
- long preserveStart = _preserve - _history;
-
- // Each cleanup is self contained so run in parallel for maximum efficiency
- Parallel.ForEach(Timers, (t) => t.Value.Cleanup(cleanupBefore, preserveStart, _preserve));
-
- Monitor.Exit(_timerQueueClearLock);
- }
-
- // Only sleep if queue was successfully cleared
- if (queueCleared)
- {
- Thread.Sleep(5);
- }
- }
- }
-
- private bool ClearTimerQueue()
- {
- int count = 0;
-
- while (_timerQueue.TryDequeue(out TimerQueueValue item))
- {
- if (!Timers.TryGetValue(item.Config, out TimingInfo value))
- {
- value = new TimingInfo();
- Timers.Add(item.Config, value);
- }
-
- if (item.IsBegin)
- {
- value.Begin(item.Time);
- }
- else
- {
- value.End(item.Time);
- }
-
- // Don't block for too long as memory disposal is blocked while this function runs
- if (count++ > 10000)
- {
- return false;
- }
- }
-
- return true;
- }
-
- public void FlagTime(TimingFlagType flagType)
- {
- int flagId = (int)flagType;
-
- _timingFlags[_timingFlagIndex] = new TimingFlag()
- {
- FlagType = flagType,
- Timestamp = PerformanceCounter.ElapsedTicks
- };
-
- _timingFlagCount = Math.Max(_timingFlagCount + 1, _maxFlags);
-
- // Work out average
- if (_timingFlagLast[flagId] != 0)
- {
- _timingFlagLastDelta[flagId] = _timingFlags[_timingFlagIndex].Timestamp - _timingFlagLast[flagId];
- _timingFlagAverages[flagId] = (_timingFlagAverages[flagId] == 0) ? _timingFlagLastDelta[flagId] :
- (_timingFlagLastDelta[flagId] + _timingFlagAverages[flagId]) >> 1;
- }
- _timingFlagLast[flagId] = _timingFlags[_timingFlagIndex].Timestamp;
-
- // Notify subscribers
- _timingFlagCallback?.Invoke(_timingFlags[_timingFlagIndex]);
-
- if (++_timingFlagIndex >= _maxFlags)
- {
- _timingFlagIndex = 0;
- }
- }
-
- public void BeginProfile(ProfileConfig config)
- {
- _timerQueue.Enqueue(new TimerQueueValue()
- {
- Config = config,
- IsBegin = true,
- Time = PerformanceCounter.ElapsedTicks,
- });
- }
-
- public void EndProfile(ProfileConfig config)
- {
- _timerQueue.Enqueue(new TimerQueueValue()
- {
- Config = config,
- IsBegin = false,
- Time = PerformanceCounter.ElapsedTicks,
- });
- }
-
- public string GetSession()
- {
- // Can be called from multiple threads so we need to ensure no duplicate sessions are generated
- return Interlocked.Increment(ref _sessionCounter).ToString();
- }
-
- public List<KeyValuePair<ProfileConfig, TimingInfo>> GetProfilingData()
- {
- _preserve = PerformanceCounter.ElapsedTicks;
-
- lock (_timerQueueClearLock)
- {
- ClearTimerQueue();
- return Timers.ToList();
- }
- }
-
- public TimingFlag[] GetTimingFlags()
- {
- int count = Math.Max(_timingFlagCount, _maxFlags);
- TimingFlag[] outFlags = new TimingFlag[count];
-
- for (int i = 0, sourceIndex = _timingFlagIndex; i < count; i++, sourceIndex++)
- {
- if (sourceIndex >= _maxFlags)
- sourceIndex = 0;
- outFlags[i] = _timingFlags[sourceIndex];
- }
-
- return outFlags;
- }
-
- public (long[], long[]) GetTimingAveragesAndLast()
- {
- return (_timingFlagAverages, _timingFlagLastDelta);
- }
-
- public void RegisterFlagReceiver(Action<TimingFlag> receiver)
- {
- _timingFlagCallback = receiver;
- }
-
- public void Dispose()
- {
- _cleanupRunning = false;
- _cleanupThread.Join();
- }
- }
-}