| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- using Ryujinx.Common;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- namespace Ryujinx.HLE.HOS.Kernel
- {
- class KTimeManager : IDisposable
- {
- private class WaitingObject
- {
- public IKFutureSchedulerObject Object { get; private set; }
- public long TimePoint { get; private set; }
- public WaitingObject(IKFutureSchedulerObject Object, long TimePoint)
- {
- this.Object = Object;
- this.TimePoint = TimePoint;
- }
- }
- private List<WaitingObject> WaitingObjects;
- private AutoResetEvent WaitEvent;
- private bool KeepRunning;
- public KTimeManager()
- {
- WaitingObjects = new List<WaitingObject>();
- KeepRunning = true;
- Thread Work = new Thread(WaitAndCheckScheduledObjects);
- Work.Start();
- }
- public void ScheduleFutureInvocation(IKFutureSchedulerObject Object, long Timeout)
- {
- long TimePoint = PerformanceCounter.ElapsedMilliseconds + ConvertNanosecondsToMilliseconds(Timeout);
- lock (WaitingObjects)
- {
- WaitingObjects.Add(new WaitingObject(Object, TimePoint));
- }
- WaitEvent.Set();
- }
- public static long ConvertNanosecondsToMilliseconds(long Time)
- {
- Time /= 1000000;
- if ((ulong)Time > int.MaxValue)
- {
- return int.MaxValue;
- }
- return Time;
- }
- public static long ConvertMillisecondsToNanoseconds(long Time)
- {
- return Time * 1000000;
- }
- public static long ConvertMillisecondsToTicks(long Time)
- {
- return Time * 19200;
- }
- public void UnscheduleFutureInvocation(IKFutureSchedulerObject Object)
- {
- lock (WaitingObjects)
- {
- WaitingObjects.RemoveAll(x => x.Object == Object);
- }
- }
- private void WaitAndCheckScheduledObjects()
- {
- using (WaitEvent = new AutoResetEvent(false))
- {
- while (KeepRunning)
- {
- WaitingObject Next;
- lock (WaitingObjects)
- {
- Next = WaitingObjects.OrderBy(x => x.TimePoint).FirstOrDefault();
- }
- if (Next != null)
- {
- long TimePoint = PerformanceCounter.ElapsedMilliseconds;
- if (Next.TimePoint > TimePoint)
- {
- WaitEvent.WaitOne((int)(Next.TimePoint - TimePoint));
- }
- bool TimeUp = PerformanceCounter.ElapsedMilliseconds >= Next.TimePoint;
- if (TimeUp)
- {
- lock (WaitingObjects)
- {
- TimeUp = WaitingObjects.Remove(Next);
- }
- }
- if (TimeUp)
- {
- Next.Object.TimeUp();
- }
- }
- else
- {
- WaitEvent.WaitOne();
- }
- }
- }
- }
- public void Dispose()
- {
- Dispose(true);
- }
- protected virtual void Dispose(bool Disposing)
- {
- if (Disposing)
- {
- KeepRunning = false;
- WaitEvent?.Set();
- }
- }
- }
- }
|