[WIP] Add support for events (#60)

* Add support for events, move concept of domains to IpcService

* Support waiting for KThread, remove some test code, other tweaks

* Use move handle on NIFM since I can't test that now, it's better to leave it how it was
This commit is contained in:
gdkchan 2018-03-19 15:58:46 -03:00 committed by GitHub
parent 4940cf0ea5
commit 4314a8f3e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
101 changed files with 1120 additions and 836 deletions

View file

@ -1,48 +0,0 @@
using System;
namespace Ryujinx.Core.OsHle.Handles
{
class HDomain : HSession, IDisposable
{
private IdDictionary Objects;
public HDomain(HSession Session) : base(Session)
{
Objects = new IdDictionary();
}
public int Add(object Obj)
{
return Objects.Add(Obj);
}
public bool Delete(int Id)
{
return Objects.Delete(Id);
}
public object GetObject(int Id)
{
return Objects.GetData(Id);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
foreach (object Obj in Objects)
{
if (Obj != this && Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
}
}
}
}
}

View file

@ -1,7 +0,0 @@
namespace Ryujinx.Core.OsHle.Handles
{
class HEvent
{
}
}

View file

@ -1,29 +0,0 @@
using Ryujinx.Core.OsHle.IpcServices;
namespace Ryujinx.Core.OsHle.Handles
{
class HSession
{
public IIpcService Service { get; private set; }
public bool IsInitialized { get; private set; }
public int State { get; set; }
public HSession(IIpcService Service)
{
this.Service = Service;
}
public HSession(HSession Session)
{
Service = Session.Service;
IsInitialized = Session.IsInitialized;
}
public void Initialize()
{
IsInitialized = true;
}
}
}

View file

@ -1,30 +0,0 @@
using System;
namespace Ryujinx.Core.OsHle.Handles
{
class HSessionObj : HSession, IDisposable
{
public object Obj { get; private set; }
public HSessionObj(HSession Session, object Obj) : base(Session)
{
this.Obj = Obj;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing && Obj != null)
{
if (Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
}
}
}
}

View file

@ -0,0 +1,4 @@
namespace Ryujinx.Core.OsHle.Handles
{
class KEvent : KSynchronizationObject { }
}

View file

@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.Handles
{
class KProcessHandleTable : IDisposable
class KProcessHandleTable
{
private IdDictionary Handles;
@ -21,43 +21,14 @@ namespace Ryujinx.Core.OsHle.Handles
return Handles.GetData<T>(Handle);
}
public bool ReplaceData(int Id, object Data)
public object CloseHandle(int Handle)
{
return Handles.ReplaceData(Id, Data);
}
public bool CloseHandle(int Handle)
{
object Data = Handles.GetData(Handle);
if (Data is HTransferMem TMem)
{
TMem.Memory.Manager.Reprotect(
TMem.Position,
TMem.Size,
TMem.Perm);
}
return Handles.Delete(Handle);
}
public void Dispose()
public ICollection<object> Clear()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
foreach (object Obj in Handles)
{
if (Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
}
}
return Handles.Clear();
}
}
}

View file

@ -5,15 +5,15 @@ using System.Threading;
namespace Ryujinx.Core.OsHle.Handles
{
public class KProcessScheduler : IDisposable
class KProcessScheduler : IDisposable
{
private class SchedulerThread : IDisposable
{
public HThread Thread { get; private set; }
public KThread Thread { get; private set; }
public AutoResetEvent WaitEvent { get; private set; }
public SchedulerThread(HThread Thread)
public SchedulerThread(KThread Thread)
{
this.Thread = Thread;
@ -95,7 +95,7 @@ namespace Ryujinx.Core.OsHle.Handles
}
}
private ConcurrentDictionary<HThread, SchedulerThread> AllThreads;
private ConcurrentDictionary<KThread, SchedulerThread> AllThreads;
private ThreadQueue[] WaitingToRun;
@ -105,7 +105,7 @@ namespace Ryujinx.Core.OsHle.Handles
public KProcessScheduler()
{
AllThreads = new ConcurrentDictionary<HThread, SchedulerThread>();
AllThreads = new ConcurrentDictionary<KThread, SchedulerThread>();
WaitingToRun = new ThreadQueue[4];
@ -119,7 +119,7 @@ namespace Ryujinx.Core.OsHle.Handles
SchedLock = new object();
}
public void StartThread(HThread Thread)
public void StartThread(KThread Thread)
{
lock (SchedLock)
{
@ -164,7 +164,7 @@ namespace Ryujinx.Core.OsHle.Handles
}
}
public void Resume(HThread CurrThread)
public void Resume(KThread CurrThread)
{
SchedulerThread SchedThread;
@ -183,7 +183,7 @@ namespace Ryujinx.Core.OsHle.Handles
TryResumingExecution(SchedThread);
}
public bool WaitForSignal(HThread Thread, int Timeout = -1)
public bool WaitForSignal(KThread Thread, int Timeout = -1)
{
SchedulerThread SchedThread;
@ -230,7 +230,7 @@ namespace Ryujinx.Core.OsHle.Handles
private void TryResumingExecution(SchedulerThread SchedThread)
{
HThread Thread = SchedThread.Thread;
KThread Thread = SchedThread.Thread;
lock (SchedLock)
{
@ -249,7 +249,7 @@ namespace Ryujinx.Core.OsHle.Handles
Logging.Debug($"{GetDbgThreadInfo(Thread)} resuming execution...");
}
public void Yield(HThread Thread)
public void Yield(KThread Thread)
{
SchedulerThread SchedThread;
@ -295,11 +295,11 @@ namespace Ryujinx.Core.OsHle.Handles
}
}
public void Signal(params HThread[] Threads)
public void Signal(params KThread[] Threads)
{
lock (SchedLock)
{
foreach (HThread Thread in Threads)
foreach (KThread Thread in Threads)
{
if (AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread))
{
@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.Handles
}
}
private string GetDbgThreadInfo(HThread Thread)
private string GetDbgThreadInfo(KThread Thread)
{
return $"Thread {Thread.ThreadId} (core {Thread.ProcessorId}) prio {Thread.Priority}";
}

View file

@ -0,0 +1,28 @@
using Ryujinx.Core.OsHle.IpcServices;
using System;
namespace Ryujinx.Core.OsHle.Handles
{
class KSession : IDisposable
{
public IpcService Service { get; private set; }
public KSession(IpcService Service)
{
this.Service = Service;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing && Service is IDisposable DisposableService)
{
DisposableService.Dispose();
}
}
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.Threading;
namespace Ryujinx.Core.OsHle.Handles
{
class KSynchronizationObject : IDisposable
{
public ManualResetEvent Handle { get; private set; }
public KSynchronizationObject()
{
Handle = new ManualResetEvent(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
Handle.Dispose();
}
}
}
}

View file

@ -2,7 +2,7 @@ using ChocolArm64;
namespace Ryujinx.Core.OsHle.Handles
{
public class HThread
class KThread : KSynchronizationObject
{
public AThread Thread { get; private set; }
@ -11,7 +11,7 @@ namespace Ryujinx.Core.OsHle.Handles
public int ThreadId => Thread.ThreadId;
public HThread(AThread Thread, int ProcessorId, int Priority)
public KThread(AThread Thread, int ProcessorId, int Priority)
{
this.Thread = Thread;
this.ProcessorId = ProcessorId;