mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-14 20:00:17 +00:00
Implement EventType
This commit is contained in:
parent
ce86b81961
commit
6ed5c58abe
20 changed files with 334 additions and 56 deletions
|
@ -1228,17 +1228,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
||||||
|
|
||||||
foreach (KThread thread in WaitingThreads)
|
foreach (KThread thread in WaitingThreads)
|
||||||
{
|
{
|
||||||
WakeAndSetResult(thread, result);
|
WakeAndSetResult(thread, result, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelContext.CriticalSection.Leave();
|
KernelContext.CriticalSection.Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WakeAndSetResult(KThread thread, Result result)
|
private void WakeAndSetResult(KThread thread, Result result, KSynchronizationObject signaledObj = null)
|
||||||
{
|
{
|
||||||
if ((thread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
|
if ((thread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused)
|
||||||
{
|
{
|
||||||
thread.SignaledObj = null;
|
thread.SignaledObj = signaledObj;
|
||||||
thread.ObjSyncResult = result;
|
thread.ObjSyncResult = result;
|
||||||
|
|
||||||
thread.Reschedule(ThreadSchedState.Running);
|
thread.Reschedule(ThreadSchedState.Running);
|
||||||
|
|
|
@ -22,8 +22,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
public bool Running { get; private set; } = true;
|
public bool Running { get; private set; } = true;
|
||||||
|
|
||||||
public ulong GetX(int index) => 0UL;
|
private readonly ulong[] _x = new ulong[32];
|
||||||
public void SetX(int index, ulong value) { }
|
|
||||||
|
public ulong GetX(int index) => _x[index];
|
||||||
|
public void SetX(int index, ulong value) => _x[index] = value;
|
||||||
|
|
||||||
public V128 GetV(int index) => default;
|
public V128 GetV(int index) => default;
|
||||||
public void SetV(int index, V128 value) { }
|
public void SetV(int index, V128 value) { }
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
public bool Running => _context.Running;
|
public bool Running => _context.Running;
|
||||||
public ulong TlsAddress => (ulong)_context.TpidrroEl0;
|
public ulong TlsAddress => (ulong)_context.TpidrroEl0;
|
||||||
|
|
||||||
|
public ulong GetX(int index) => _context.GetX(index);
|
||||||
|
|
||||||
private int _locked;
|
private int _locked;
|
||||||
|
|
||||||
public KThreadContext(IExecutionContext context)
|
public KThreadContext(IExecutionContext context)
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Ryujinx.Horizon.Common
|
||||||
Result CloseHandle(int handle);
|
Result CloseHandle(int handle);
|
||||||
|
|
||||||
Result WaitSynchronization(out int handleIndex, ReadOnlySpan<int> handles, long timeout);
|
Result WaitSynchronization(out int handleIndex, ReadOnlySpan<int> handles, long timeout);
|
||||||
|
Result CancelSynchronization(int handle);
|
||||||
|
|
||||||
Result GetProcessId(out ulong pid, int handle);
|
Result GetProcessId(out ulong pid, int handle);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using System.Runtime.Intrinsics;
|
namespace Ryujinx.Horizon.Common
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Common
|
|
||||||
{
|
{
|
||||||
public interface IThreadContext
|
public interface IThreadContext
|
||||||
{
|
{
|
||||||
bool Running { get; }
|
bool Running { get; }
|
||||||
|
|
||||||
ulong TlsAddress { get; }
|
ulong TlsAddress { get; }
|
||||||
|
|
||||||
|
ulong GetX(int index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Common
|
namespace Ryujinx.Horizon.Common
|
||||||
{
|
{
|
||||||
class InvalidResultException : Exception
|
public class InvalidResultException : Exception
|
||||||
{
|
{
|
||||||
public InvalidResultException()
|
public InvalidResultException()
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,6 +76,11 @@ namespace Ryujinx.Horizon.Common
|
||||||
|
|
||||||
public void AbortOnFailure()
|
public void AbortOnFailure()
|
||||||
{
|
{
|
||||||
|
if (this == KernelResult.ThreadTerminating)
|
||||||
|
{
|
||||||
|
throw new ThreadTerminatedException();
|
||||||
|
}
|
||||||
|
|
||||||
AbortUnless(Success);
|
AbortUnless(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
Ryujinx.Horizon.Common/ThreadTerminatedException.cs
Normal file
19
Ryujinx.Horizon.Common/ThreadTerminatedException.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Common
|
||||||
|
{
|
||||||
|
public class ThreadTerminatedException : Exception
|
||||||
|
{
|
||||||
|
public ThreadTerminatedException() : base("The thread has been terminated.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadTerminatedException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThreadTerminatedException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,21 +18,27 @@ namespace Ryujinx.Horizon
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static IThreadContext _threadContext;
|
private static IThreadContext _threadContext;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int _threadHandle;
|
||||||
|
|
||||||
public static HorizonOptions Options => _options;
|
public static HorizonOptions Options => _options;
|
||||||
public static ISyscallApi Syscall => _syscall;
|
public static ISyscallApi Syscall => _syscall;
|
||||||
public static IVirtualMemoryManager AddressSpace => _addressSpace;
|
public static IVirtualMemoryManager AddressSpace => _addressSpace;
|
||||||
public static IThreadContext ThreadContext => _threadContext;
|
public static IThreadContext ThreadContext => _threadContext;
|
||||||
|
public static int CurrentThreadHandle => _threadHandle;
|
||||||
|
|
||||||
public static void Register(
|
public static void Register(
|
||||||
HorizonOptions options,
|
HorizonOptions options,
|
||||||
ISyscallApi syscallApi,
|
ISyscallApi syscallApi,
|
||||||
IVirtualMemoryManager addressSpace,
|
IVirtualMemoryManager addressSpace,
|
||||||
IThreadContext threadContext)
|
IThreadContext threadContext,
|
||||||
|
int threadHandle)
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_syscall = syscallApi;
|
_syscall = syscallApi;
|
||||||
_addressSpace = addressSpace;
|
_addressSpace = addressSpace;
|
||||||
_threadContext = threadContext;
|
_threadContext = threadContext;
|
||||||
|
_threadHandle = threadHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,61 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.OsTypes
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
class Event
|
class Event : IDisposable
|
||||||
{
|
{
|
||||||
// TODO: Actually implement this.
|
private EventType _event;
|
||||||
|
|
||||||
private bool _autoClear;
|
public object EventLock => _event.Lock;
|
||||||
private bool _isSignaled;
|
public LinkedList<MultiWaitHolderBase> MultiWaitHolders => _event.MultiWaitHolders;
|
||||||
|
|
||||||
public Event(bool autoClear, bool isSignaled = false)
|
public Event(EventClearMode clearMode)
|
||||||
{
|
{
|
||||||
_autoClear = autoClear;
|
Os.InitializeEvent(out _event, signaled: false, clearMode);
|
||||||
_isSignaled = isSignaled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public TriBool IsSignaledThreadUnsafe()
|
||||||
{
|
{
|
||||||
_isSignaled = false;
|
return _event.Signaled ? TriBool.True : TriBool.False;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Wait()
|
||||||
|
{
|
||||||
|
Os.WaitEvent(ref _event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryWait()
|
||||||
|
{
|
||||||
|
return Os.TryWaitEvent(ref _event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TimedWait(TimeSpan timeout)
|
||||||
|
{
|
||||||
|
return Os.TimedWaitEvent(ref _event, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Signal()
|
public void Signal()
|
||||||
{
|
{
|
||||||
_isSignaled = true;
|
Os.SignalEvent(ref _event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
Os.ClearEvent(ref _event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
Os.FinalizeEvent(ref _event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.OsTypes
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
struct EventType
|
struct EventType
|
||||||
{
|
{
|
||||||
|
public LinkedList<MultiWaitHolderBase> MultiWaitHolders;
|
||||||
public bool Signaled;
|
public bool Signaled;
|
||||||
public bool InitiallySignaled;
|
public bool InitiallySignaled;
|
||||||
public byte ClearMode;
|
public EventClearMode ClearMode;
|
||||||
public InitializationState State;
|
public InitializationState State;
|
||||||
public ulong BroadcastCounter;
|
public ulong BroadcastCounter;
|
||||||
|
public object Lock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,8 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
|
|
||||||
public MultiWaitHolderBase WaitAnyImpl(bool infinite, long timeout)
|
public MultiWaitHolderBase WaitAnyImpl(bool infinite, long timeout)
|
||||||
{
|
{
|
||||||
_waitingThreadHandle = Os.GetCurrentThreadHandle();
|
|
||||||
|
|
||||||
_signaledHolder = null;
|
_signaledHolder = null;
|
||||||
|
_waitingThreadHandle = Os.GetCurrentThreadHandle();
|
||||||
|
|
||||||
MultiWaitHolderBase result = LinkHoldersToObjectList();
|
MultiWaitHolderBase result = LinkHoldersToObjectList();
|
||||||
|
|
||||||
|
@ -72,6 +71,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlinkHoldersFromObjectsList();
|
UnlinkHoldersFromObjectsList();
|
||||||
|
_waitingThreadHandle = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -84,13 +84,13 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
|
|
||||||
int count = FillObjectsArray(objectHandles, objects);
|
int count = FillObjectsArray(objectHandles, objects);
|
||||||
|
|
||||||
long endTime = infinite ? -1L : PerformanceCounter.ElapsedMilliseconds * 1000000;
|
long endTime = infinite ? long.MaxValue : PerformanceCounter.ElapsedMilliseconds * 1000000;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
CurrentTime = PerformanceCounter.ElapsedMilliseconds * 1000000;
|
CurrentTime = PerformanceCounter.ElapsedMilliseconds * 1000000;
|
||||||
|
|
||||||
MultiWaitHolderBase minTimeoutObject = RecalculateNextTimepoint(endTime, out long minTimeout);
|
MultiWaitHolderBase minTimeoutObject = RecalcMultiWaitTimeout(endTime, out long minTimeout);
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiWaitHolderBase RecalculateNextTimepoint(long endTime, out long minTimeout)
|
private MultiWaitHolderBase RecalcMultiWaitTimeout(long endTime, out long minTimeout)
|
||||||
{
|
{
|
||||||
MultiWaitHolderBase minTimeHolder = null;
|
MultiWaitHolderBase minTimeHolder = null;
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
|
|
||||||
foreach (MultiWaitHolder holder in _multiWaits)
|
foreach (MultiWaitHolder holder in _multiWaits)
|
||||||
{
|
{
|
||||||
long currentTime = holder.GetWakeUpTime();
|
long currentTime = holder.GetAbsoluteTimeToWakeup();
|
||||||
|
|
||||||
if ((ulong)currentTime < (ulong)minTime)
|
if ((ulong)currentTime < (ulong)minTime)
|
||||||
{
|
{
|
||||||
|
@ -207,6 +207,18 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void NotifyAndWakeUpThread(MultiWaitHolderBase holder)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (_signaledHolder == null)
|
||||||
|
{
|
||||||
|
_signaledHolder = holder;
|
||||||
|
HorizonStatic.Syscall.CancelSynchronization(_waitingThreadHandle).AbortOnFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private MultiWaitHolderBase LinkHoldersToObjectList()
|
private MultiWaitHolderBase LinkHoldersToObjectList()
|
||||||
{
|
{
|
||||||
MultiWaitHolderBase signaledHolder = null;
|
MultiWaitHolderBase signaledHolder = null;
|
||||||
|
|
|
@ -17,10 +17,23 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
MultiWait = multiWait;
|
MultiWait = multiWait;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual TriBool LinkToObjectList() => TriBool.Undefined;
|
public MultiWaitImpl GetMultiWait()
|
||||||
|
{
|
||||||
|
return MultiWait;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void UnlinkFromObjectList() { }
|
public virtual TriBool LinkToObjectList()
|
||||||
|
{
|
||||||
|
return TriBool.Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual long GetWakeUpTime() => -1L;
|
public virtual void UnlinkFromObjectList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual long GetAbsoluteTimeToWakeup()
|
||||||
|
{
|
||||||
|
return long.MaxValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
44
Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfEvent.cs
Normal file
44
Ryujinx.Horizon/Sdk/OsTypes/MultiWaitHolderOfEvent.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
|
{
|
||||||
|
class MultiWaitHolderOfEvent : MultiWaitHolder
|
||||||
|
{
|
||||||
|
private Event _event;
|
||||||
|
private LinkedListNode<MultiWaitHolderBase> _node;
|
||||||
|
|
||||||
|
public override TriBool Signaled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_event.EventLock)
|
||||||
|
{
|
||||||
|
return _event.IsSignaledThreadUnsafe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiWaitHolderOfEvent(Event evnt)
|
||||||
|
{
|
||||||
|
_event = evnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TriBool LinkToObjectList()
|
||||||
|
{
|
||||||
|
lock (_event.EventLock)
|
||||||
|
{
|
||||||
|
_node = _event.MultiWaitHolders.AddLast(this);
|
||||||
|
return _event.IsSignaledThreadUnsafe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UnlinkFromObjectList()
|
||||||
|
{
|
||||||
|
lock (_event.EventLock)
|
||||||
|
{
|
||||||
|
_event.MultiWaitHolders.Remove(_node);
|
||||||
|
_node = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.OsTypes
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
static partial class Os
|
static partial class Os
|
||||||
{
|
{
|
||||||
|
@ -6,11 +10,121 @@
|
||||||
{
|
{
|
||||||
evnt = new EventType
|
evnt = new EventType
|
||||||
{
|
{
|
||||||
|
MultiWaitHolders = new LinkedList<MultiWaitHolderBase>(),
|
||||||
Signaled = signaled,
|
Signaled = signaled,
|
||||||
InitiallySignaled = signaled,
|
InitiallySignaled = signaled,
|
||||||
ClearMode = (byte)clearMode,
|
ClearMode = clearMode,
|
||||||
State = InitializationState.Initialized
|
State = InitializationState.Initialized,
|
||||||
|
Lock = new object()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void FinalizeEvent(ref EventType evnt)
|
||||||
|
{
|
||||||
|
evnt.State = InitializationState.NotInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WaitEvent(ref EventType evnt)
|
||||||
|
{
|
||||||
|
lock (evnt.Lock)
|
||||||
|
{
|
||||||
|
ulong currentCounter = evnt.BroadcastCounter;
|
||||||
|
|
||||||
|
while (!evnt.Signaled)
|
||||||
|
{
|
||||||
|
if (currentCounter != evnt.BroadcastCounter)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Monitor.Wait(evnt.Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evnt.ClearMode == EventClearMode.AutoClear)
|
||||||
|
{
|
||||||
|
evnt.Signaled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryWaitEvent(ref EventType evnt)
|
||||||
|
{
|
||||||
|
lock (evnt.Lock)
|
||||||
|
{
|
||||||
|
bool signaled = evnt.Signaled;
|
||||||
|
|
||||||
|
if (evnt.ClearMode == EventClearMode.AutoClear)
|
||||||
|
{
|
||||||
|
evnt.Signaled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signaled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TimedWaitEvent(ref EventType evnt, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
lock (evnt.Lock)
|
||||||
|
{
|
||||||
|
ulong currentCounter = evnt.BroadcastCounter;
|
||||||
|
|
||||||
|
while (!evnt.Signaled)
|
||||||
|
{
|
||||||
|
if (currentCounter != evnt.BroadcastCounter)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wasSignaledInTime = Monitor.Wait(evnt.Lock, timeout);
|
||||||
|
if (!wasSignaledInTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evnt.ClearMode == EventClearMode.AutoClear)
|
||||||
|
{
|
||||||
|
evnt.Signaled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SignalEvent(ref EventType evnt)
|
||||||
|
{
|
||||||
|
lock (evnt.Lock)
|
||||||
|
{
|
||||||
|
if (evnt.Signaled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
evnt.Signaled = true;
|
||||||
|
|
||||||
|
if (evnt.ClearMode == EventClearMode.ManualClear)
|
||||||
|
{
|
||||||
|
evnt.BroadcastCounter++;
|
||||||
|
Monitor.PulseAll(evnt.Lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Monitor.Pulse(evnt.Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (MultiWaitHolderBase holder in evnt.MultiWaitHolders)
|
||||||
|
{
|
||||||
|
holder.GetMultiWait().NotifyAndWakeUpThread(holder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearEvent(ref EventType evnt)
|
||||||
|
{
|
||||||
|
lock (evnt.Lock)
|
||||||
|
{
|
||||||
|
evnt.Signaled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysEvent.State = SystemEventType.InitializatonState.InitializedAsInterProcess;
|
sysEvent.State = SystemEventType.InitializationState.InitializedAsInterProcess;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -32,11 +32,11 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
public static void DestroySystemEvent(ref SystemEventType sysEvent)
|
public static void DestroySystemEvent(ref SystemEventType sysEvent)
|
||||||
{
|
{
|
||||||
var oldState = sysEvent.State;
|
var oldState = sysEvent.State;
|
||||||
sysEvent.State = SystemEventType.InitializatonState.NotInitialized;
|
sysEvent.State = SystemEventType.InitializationState.NotInitialized;
|
||||||
|
|
||||||
switch (oldState)
|
switch (oldState)
|
||||||
{
|
{
|
||||||
case SystemEventType.InitializatonState.InitializedAsInterProcess:
|
case SystemEventType.InitializationState.InitializedAsInterProcess:
|
||||||
InterProcessEvent.Destroy(ref sysEvent.InterProcessEvent);
|
InterProcessEvent.Destroy(ref sysEvent.InterProcessEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
switch (sysEvent.State)
|
switch (sysEvent.State)
|
||||||
{
|
{
|
||||||
case SystemEventType.InitializatonState.InitializedAsInterProcess:
|
case SystemEventType.InitializationState.InitializedAsInterProcess:
|
||||||
InterProcessEvent.Signal(ref sysEvent.InterProcessEvent);
|
InterProcessEvent.Signal(ref sysEvent.InterProcessEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
switch (sysEvent.State)
|
switch (sysEvent.State)
|
||||||
{
|
{
|
||||||
case SystemEventType.InitializatonState.InitializedAsInterProcess:
|
case SystemEventType.InitializationState.InitializedAsInterProcess:
|
||||||
InterProcessEvent.Clear(ref sysEvent.InterProcessEvent);
|
InterProcessEvent.Clear(ref sysEvent.InterProcessEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
{
|
{
|
||||||
public static int GetCurrentThreadHandle()
|
public static int GetCurrentThreadHandle()
|
||||||
{
|
{
|
||||||
// TODO.
|
return HorizonStatic.CurrentThreadHandle;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
struct SystemEventType
|
struct SystemEventType
|
||||||
{
|
{
|
||||||
public enum InitializatonState : byte
|
public enum InitializationState : byte
|
||||||
{
|
{
|
||||||
NotInitialized,
|
NotInitialized,
|
||||||
InitializedAsEvent,
|
InitializedAsEvent,
|
||||||
|
@ -10,8 +10,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public InterProcessEventType InterProcessEvent;
|
public InterProcessEventType InterProcessEvent;
|
||||||
public InitializatonState State;
|
public InitializationState State;
|
||||||
|
|
||||||
public bool NotInitialized => State == InitializatonState.NotInitialized;
|
public bool NotInitialized => State == InitializationState.NotInitialized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ using Ryujinx.Horizon.Common;
|
||||||
using Ryujinx.Horizon.Sdk.Sf.Cmif;
|
using Ryujinx.Horizon.Sdk.Sf.Cmif;
|
||||||
using Ryujinx.Horizon.Sdk.Sm;
|
using Ryujinx.Horizon.Sdk.Sm;
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.Horizon.Sm;
|
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
|
@ -19,6 +18,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
private readonly object _waitableSelectionLock;
|
private readonly object _waitableSelectionLock;
|
||||||
private readonly object _waitListLock;
|
private readonly object _waitListLock;
|
||||||
|
|
||||||
|
private readonly Event _requestStopEvent;
|
||||||
private readonly Event _notifyEvent;
|
private readonly Event _notifyEvent;
|
||||||
|
|
||||||
private readonly MultiWaitHolderBase _requestStopEventHolder;
|
private readonly MultiWaitHolderBase _requestStopEventHolder;
|
||||||
|
@ -41,7 +41,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
_waitableSelectionLock = new object();
|
_waitableSelectionLock = new object();
|
||||||
_waitListLock = new object();
|
_waitListLock = new object();
|
||||||
|
|
||||||
_notifyEvent = new Event(false);
|
_requestStopEvent = new Event(EventClearMode.ManualClear);
|
||||||
|
_notifyEvent = new Event(EventClearMode.ManualClear);
|
||||||
|
|
||||||
|
_requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent);
|
||||||
|
_multiWait.LinkMultiWaitHolder(_requestStopEventHolder);
|
||||||
|
_notifyEventHolder = new MultiWaitHolderOfEvent(_notifyEvent);
|
||||||
|
_multiWait.LinkMultiWaitHolder(_notifyEventHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterObjectForServer(IServiceObject staticObject, int portHandle)
|
public void RegisterObjectForServer(IServiceObject staticObject, int portHandle)
|
||||||
|
@ -109,16 +115,23 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
private bool WaitAndProcessRequestsImpl()
|
private bool WaitAndProcessRequestsImpl()
|
||||||
{
|
{
|
||||||
MultiWaitHolder waitable = WaitSignaled();
|
try
|
||||||
|
{
|
||||||
|
MultiWaitHolder multiWait = WaitSignaled();
|
||||||
|
|
||||||
if (waitable == null)
|
if (multiWait == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugUtil.Assert(Process(multiWait).IsSuccess);
|
||||||
|
|
||||||
|
return HorizonStatic.ThreadContext.Running;
|
||||||
|
}
|
||||||
|
catch (ThreadTerminatedException)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugUtil.Assert(Process(waitable).IsSuccess);
|
|
||||||
|
|
||||||
return HorizonStatic.ThreadContext.Running;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiWaitHolder WaitSignaled()
|
private MultiWaitHolder WaitSignaled()
|
||||||
|
@ -137,7 +150,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
}
|
}
|
||||||
else if (selected == _notifyEventHolder)
|
else if (selected == _notifyEventHolder)
|
||||||
{
|
{
|
||||||
_notifyEvent.Reset();
|
_notifyEvent.Clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -149,6 +162,16 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResumeProcessing()
|
||||||
|
{
|
||||||
|
_requestStopEvent.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestStopProcessing()
|
||||||
|
{
|
||||||
|
_requestStopEvent.Signal();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void RegisterSessionToWaitList(ServerSession session)
|
protected override void RegisterSessionToWaitList(ServerSession session)
|
||||||
{
|
{
|
||||||
session.HasReceived = false;
|
session.HasReceived = false;
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Horizon
|
||||||
|
|
||||||
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
||||||
{
|
{
|
||||||
HorizonStatic.Register(_options, syscallApi, addressSpace, threadContext);
|
HorizonStatic.Register(_options, syscallApi, addressSpace, threadContext, (int)threadContext.GetX(1));
|
||||||
|
|
||||||
_entrypoint();
|
_entrypoint();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue