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

This commit is contained in:
gdkchan 2018-03-19 15:49:02 -03:00
commit 2d119966b3
17 changed files with 167 additions and 173 deletions

View file

@ -13,7 +13,7 @@ namespace Ryujinx.Core.OsHle
private bool OwnsCondVarValue; private bool OwnsCondVarValue;
private List<HThread> WaitingThreads; private List<KThread> WaitingThreads;
public CondVar(Process Process, long CondVarAddress, long Timeout) public CondVar(Process Process, long CondVarAddress, long Timeout)
{ {
@ -21,10 +21,10 @@ namespace Ryujinx.Core.OsHle
this.CondVarAddress = CondVarAddress; this.CondVarAddress = CondVarAddress;
this.Timeout = Timeout; this.Timeout = Timeout;
WaitingThreads = new List<HThread>(); WaitingThreads = new List<KThread>();
} }
public bool WaitForSignal(HThread Thread) public bool WaitForSignal(KThread Thread)
{ {
int Count = Process.Memory.ReadInt32(CondVarAddress); int Count = Process.Memory.ReadInt32(CondVarAddress);
@ -66,7 +66,7 @@ namespace Ryujinx.Core.OsHle
return true; return true;
} }
public void SetSignal(HThread Thread, int Count) public void SetSignal(KThread Thread, int Count)
{ {
lock (WaitingThreads) lock (WaitingThreads)
{ {

View file

@ -1,4 +1,5 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle namespace Ryujinx.Core.OsHle
{ {
@ -38,14 +39,24 @@ namespace Ryujinx.Core.OsHle
return default(T); return default(T);
} }
public bool Delete(Process Process, int Id) public object Delete(Process Process, int Id)
{ {
if (DictByProcess.TryGetValue(Process, out IdDictionary Dict)) if (DictByProcess.TryGetValue(Process, out IdDictionary Dict))
{ {
return Dict.Delete(Id); return Dict.Delete(Id);
} }
return false; return null;
}
public ICollection<object> DeleteProcess(Process Process)
{
if (DictByProcess.TryRemove(Process, out IdDictionary Dict))
{
return Dict.Clear();
}
return null;
} }
} }
} }

View file

@ -1,8 +1,8 @@
using System; using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.Handles namespace Ryujinx.Core.OsHle.Handles
{ {
class KProcessHandleTable : IDisposable class KProcessHandleTable
{ {
private IdDictionary Handles; private IdDictionary Handles;
@ -13,14 +13,7 @@ namespace Ryujinx.Core.OsHle.Handles
public int OpenHandle(object Obj) public int OpenHandle(object Obj)
{ {
int h = Handles.Add(Obj); return Handles.Add(Obj);
/*if (h == 0x1d)
{
throw new System.Exception("bad handle");
}*/
return h;
} }
public T GetData<T>(int Handle) public T GetData<T>(int Handle)
@ -28,38 +21,14 @@ namespace Ryujinx.Core.OsHle.Handles
return Handles.GetData<T>(Handle); return Handles.GetData<T>(Handle);
} }
public bool CloseHandle(int Handle) public object 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); return Handles.Delete(Handle);
} }
public void Dispose() public ICollection<object> Clear()
{ {
Dispose(true); return Handles.Clear();
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
foreach (object Obj in Handles)
{
if (Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
}
}
} }
} }
} }

View file

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

View file

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

View file

@ -1,12 +1,10 @@
using Ryujinx.Core.OsHle.Handles;
using System; using System;
using System.Collections;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Core.OsHle namespace Ryujinx.Core.OsHle
{ {
class IdDictionary : IEnumerable<object> class IdDictionary
{ {
private ConcurrentDictionary<int, object> Objs; private ConcurrentDictionary<int, object> Objs;
@ -60,31 +58,25 @@ namespace Ryujinx.Core.OsHle
return default(T); return default(T);
} }
public bool Delete(int Id) public object Delete(int Id)
{ {
if (Objs.TryRemove(Id, out object Obj)) if (Objs.TryRemove(Id, out object Obj))
{ {
if (Obj is IDisposable DisposableObj && !(Obj is KEvent))
{
DisposableObj.Dispose();
}
FreeIdHint = Id; FreeIdHint = Id;
return true; return Obj;
} }
return false; return null;
} }
IEnumerator<object> IEnumerable<object>.GetEnumerator() public ICollection<object> Clear()
{ {
return Objs.Values.GetEnumerator(); ICollection<object> Values = Objs.Values;
}
IEnumerator IEnumerable.GetEnumerator() Objs.Clear();
{
return Objs.Values.GetEnumerator(); return Values;
} }
} }
} }

View file

@ -13,8 +13,7 @@ namespace Ryujinx.Core.OsHle.Ipc
AMemory Memory, AMemory Memory,
KSession Session, KSession Session,
IpcMessage Request, IpcMessage Request,
long CmdPtr, long CmdPtr)
int HndId)
{ {
IpcMessage Response = new IpcMessage(); IpcMessage Response = new IpcMessage();

View file

@ -16,7 +16,7 @@ namespace Ryujinx.Core.OsHle
private object EnterWaitLock; private object EnterWaitLock;
private ConcurrentQueue<HThread> WaitingThreads; private ConcurrentQueue<KThread> WaitingThreads;
public Mutex(Process Process, long MutexAddress, int OwnerThreadHandle) public Mutex(Process Process, long MutexAddress, int OwnerThreadHandle)
{ {
@ -27,10 +27,10 @@ namespace Ryujinx.Core.OsHle
EnterWaitLock = new object(); EnterWaitLock = new object();
WaitingThreads = new ConcurrentQueue<HThread>(); WaitingThreads = new ConcurrentQueue<KThread>();
} }
public void WaitForLock(HThread RequestingThread, int RequestingThreadHandle) public void WaitForLock(KThread RequestingThread, int RequestingThreadHandle)
{ {
AcquireMutexValue(); AcquireMutexValue();
@ -83,11 +83,11 @@ namespace Ryujinx.Core.OsHle
ReleaseMutexValue(); ReleaseMutexValue();
HThread[] UnlockedThreads = new HThread[WaitingThreads.Count]; KThread[] UnlockedThreads = new KThread[WaitingThreads.Count];
int Index = 0; int Index = 0;
while (WaitingThreads.TryDequeue(out HThread Thread)) while (WaitingThreads.TryDequeue(out KThread Thread))
{ {
UnlockedThreads[Index++] = Thread; UnlockedThreads[Index++] = Thread;
} }

View file

@ -5,6 +5,7 @@ using Ryujinx.Core.Loaders;
using Ryujinx.Core.Loaders.Executables; using Ryujinx.Core.Loaders.Executables;
using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Exceptions;
using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.IpcServices.NvServices;
using Ryujinx.Core.OsHle.Svc; using Ryujinx.Core.OsHle.Svc;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -41,11 +42,11 @@ namespace Ryujinx.Core.OsHle
private ConcurrentDictionary<int, AThread> TlsSlots; private ConcurrentDictionary<int, AThread> TlsSlots;
private ConcurrentDictionary<long, HThread> ThreadsByTpidr; private ConcurrentDictionary<long, KThread> ThreadsByTpidr;
private List<Executable> Executables; private List<Executable> Executables;
private HThread MainThread; private KThread MainThread;
private long ImageBase; private long ImageBase;
@ -70,7 +71,7 @@ namespace Ryujinx.Core.OsHle
TlsSlots = new ConcurrentDictionary<int, AThread>(); TlsSlots = new ConcurrentDictionary<int, AThread>();
ThreadsByTpidr = new ConcurrentDictionary<long, HThread>(); ThreadsByTpidr = new ConcurrentDictionary<long, KThread>();
Executables = new List<Executable>(); Executables = new List<Executable>();
@ -132,7 +133,7 @@ namespace Ryujinx.Core.OsHle
return false; return false;
} }
MainThread = HandleTable.GetData<HThread>(Handle); MainThread = HandleTable.GetData<KThread>(Handle);
if (NeedsHbAbi) if (NeedsHbAbi)
{ {
@ -186,7 +187,7 @@ namespace Ryujinx.Core.OsHle
AThread Thread = new AThread(GetTranslator(), Memory, EntryPoint); AThread Thread = new AThread(GetTranslator(), Memory, EntryPoint);
HThread ThreadHnd = new HThread(Thread, ProcessorId, Priority); KThread ThreadHnd = new KThread(Thread, ProcessorId, Priority);
int Handle = HandleTable.OpenHandle(ThreadHnd); int Handle = HandleTable.OpenHandle(ThreadHnd);
@ -311,9 +312,9 @@ namespace Ryujinx.Core.OsHle
return (int)((Position - MemoryRegions.TlsPagesAddress) / TlsSize); return (int)((Position - MemoryRegions.TlsPagesAddress) / TlsSize);
} }
public HThread GetThread(long Tpidr) public KThread GetThread(long Tpidr)
{ {
if (!ThreadsByTpidr.TryGetValue(Tpidr, out HThread Thread)) if (!ThreadsByTpidr.TryGetValue(Tpidr, out KThread Thread))
{ {
Logging.Error($"Thread with TPIDR 0x{Tpidr:x16} not found!"); Logging.Error($"Thread with TPIDR 0x{Tpidr:x16} not found!");
} }
@ -345,7 +346,19 @@ namespace Ryujinx.Core.OsHle
Disposed = true; Disposed = true;
HandleTable.Dispose(); foreach (object Obj in HandleTable.Clear())
{
if (Obj is KSession Session)
{
Session.Dispose();
}
}
ServiceNvDrv.Fds.DeleteProcess(this);
ServiceNvDrv.NvMaps.DeleteProcess(this);
ServiceNvDrv.NvMapsById.DeleteProcess(this);
Scheduler.Dispose(); Scheduler.Dispose();

View file

@ -40,21 +40,6 @@ namespace Ryujinx.Core.OsHle.IpcServices
IsDomain = false; IsDomain = false;
} }
private int Add(IIpcService Obj)
{
return DomainObjects.Add(Obj);
}
private bool Delete(int Id)
{
return DomainObjects.Delete(Id);
}
private IIpcService GetObject(int Id)
{
return DomainObjects.GetData<IIpcService>(Id);
}
public void CallMethod(ServiceCtx Context) public void CallMethod(ServiceCtx Context)
{ {
IIpcService Service = this; IIpcService Service = this;
@ -140,5 +125,27 @@ namespace Ryujinx.Core.OsHle.IpcServices
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
} }
} }
private int Add(IIpcService Obj)
{
return DomainObjects.Add(Obj);
}
private bool Delete(int Id)
{
object Obj = DomainObjects.Delete(Id);
if (Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
return Obj != null;
}
private IIpcService GetObject(int Id)
{
return DomainObjects.GetData<IIpcService>(Id);
}
} }
} }

View file

@ -18,7 +18,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds; private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds;
private static GlobalStateTable Fds; public static GlobalStateTable Fds { get; private set; }
public static GlobalStateTable NvMaps { get; private set; } public static GlobalStateTable NvMaps { get; private set; }
public static GlobalStateTable NvMapsById { get; private set; } public static GlobalStateTable NvMapsById { get; private set; }

View file

@ -1,4 +1,5 @@
using ChocolArm64.Memory; using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc; using Ryujinx.Core.OsHle.Ipc;
using Ryujinx.Core.OsHle.IpcServices.Android; using Ryujinx.Core.OsHle.IpcServices.Android;
using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Gal;
@ -13,6 +14,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent ReleaseEvent;
private NvFlinger Flinger; private NvFlinger Flinger;
public IHOSBinderDriver(IGalRenderer Renderer) public IHOSBinderDriver(IGalRenderer Renderer)
@ -24,7 +27,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
{ 2, GetNativeHandle } { 2, GetNativeHandle }
}; };
Flinger = new NvFlinger(Renderer); ReleaseEvent = new KEvent();
Flinger = new NvFlinger(Renderer, ReleaseEvent);
} }
public long TransactParcel(ServiceCtx Context) public long TransactParcel(ServiceCtx Context)
@ -56,7 +61,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
int Id = Context.RequestData.ReadInt32(); int Id = Context.RequestData.ReadInt32();
uint Unk = Context.RequestData.ReadUInt32(); uint Unk = Context.RequestData.ReadUInt32();
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(0xbadcafe); int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
return 0; return 0;
} }
@ -70,6 +77,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
{ {
if (Disposing) if (Disposing)
{ {
ReleaseEvent.Dispose();
Flinger.Dispose(); Flinger.Dispose();
} }
} }

View file

@ -1,4 +1,5 @@
using ChocolArm64.Memory; using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.IpcServices.NvServices; using Ryujinx.Core.OsHle.IpcServices.NvServices;
using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Gal;
using System; using System;
@ -17,6 +18,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
private Dictionary<(string, int), ServiceProcessParcel> Commands; private Dictionary<(string, int), ServiceProcessParcel> Commands;
private KEvent ReleaseEvent;
private IGalRenderer Renderer;
private const int BufferQueueCount = 0x40; private const int BufferQueueCount = 0x40;
private const int BufferQueueMask = BufferQueueCount - 1; private const int BufferQueueMask = BufferQueueCount - 1;
@ -55,8 +60,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
public GbpBuffer Data; public GbpBuffer Data;
} }
private IGalRenderer Renderer;
private BufferEntry[] BufferQueue; private BufferEntry[] BufferQueue;
private ManualResetEvent WaitBufferFree; private ManualResetEvent WaitBufferFree;
@ -69,7 +72,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
private bool KeepRunning; private bool KeepRunning;
public NvFlinger(IGalRenderer Renderer) public NvFlinger(IGalRenderer Renderer, KEvent ReleaseEvent)
{ {
Commands = new Dictionary<(string, int), ServiceProcessParcel>() Commands = new Dictionary<(string, int), ServiceProcessParcel>()
{ {
@ -85,6 +88,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
}; };
this.Renderer = Renderer; this.Renderer = Renderer;
this.ReleaseEvent = ReleaseEvent;
BufferQueue = new BufferEntry[0x40]; BufferQueue = new BufferEntry[0x40];
@ -293,6 +297,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
BufferQueue[Slot].State = BufferState.Free; BufferQueue[Slot].State = BufferState.Free;
ReleaseEvent.Handle.Set();
WaitBufferFree.Set(); WaitBufferFree.Set();
return; return;
@ -377,6 +383,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
Interlocked.Decrement(ref RenderQueueCount); Interlocked.Decrement(ref RenderQueueCount);
ReleaseEvent.Handle.Set();
lock (WaitBufferFree) lock (WaitBufferFree)
{ {
WaitBufferFree.Set(); WaitBufferFree.Set();

View file

@ -35,7 +35,28 @@ namespace Ryujinx.Core.OsHle.Svc
{ {
int Handle = (int)ThreadState.X0; int Handle = (int)ThreadState.X0;
Process.HandleTable.CloseHandle(Handle); object Obj = Process.HandleTable.CloseHandle(Handle);
if (Obj == null)
{
Logging.Warn($"Tried to CloseHandle on invalid handle 0x{Handle:x8}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
return;
}
if (Obj is KSession Session)
{
Session.Dispose();
}
else if (Obj is HTransferMem TMem)
{
TMem.Memory.Manager.Reprotect(
TMem.Position,
TMem.Size,
TMem.Perm);
}
ThreadState.X0 = 0; ThreadState.X0 = 0;
} }
@ -66,7 +87,7 @@ namespace Ryujinx.Core.OsHle.Svc
int HandlesCount = (int)ThreadState.X2; int HandlesCount = (int)ThreadState.X2;
long Timeout = (long)ThreadState.X3; long Timeout = (long)ThreadState.X3;
HThread CurrThread = Process.GetThread(ThreadState.Tpidr); KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
WaitHandle[] Handles = new WaitHandle[HandlesCount]; WaitHandle[] Handles = new WaitHandle[HandlesCount];
@ -142,32 +163,21 @@ namespace Ryujinx.Core.OsHle.Svc
private void SvcSendSyncRequest(AThreadState ThreadState) private void SvcSendSyncRequest(AThreadState ThreadState)
{ {
SendSyncRequest(ThreadState, false); SendSyncRequest(ThreadState, ThreadState.Tpidr, 0x100, (int)ThreadState.X0);
} }
private void SvcSendSyncRequestWithUserBuffer(AThreadState ThreadState) private void SvcSendSyncRequestWithUserBuffer(AThreadState ThreadState)
{ {
SendSyncRequest(ThreadState, true); SendSyncRequest(
ThreadState,
(long)ThreadState.X0,
(long)ThreadState.X1,
(int)ThreadState.X2);
} }
private void SendSyncRequest(AThreadState ThreadState, bool UserBuffer) private void SendSyncRequest(AThreadState ThreadState, long CmdPtr, long Size, int Handle)
{ {
long CmdPtr = ThreadState.Tpidr; KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
long Size = 0x100;
int Handle = 0;
if (UserBuffer)
{
CmdPtr = (long)ThreadState.X0;
Size = (long)ThreadState.X1;
Handle = (int)ThreadState.X2;
}
else
{
Handle = (int)ThreadState.X0;
}
HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size);
@ -179,14 +189,7 @@ namespace Ryujinx.Core.OsHle.Svc
IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr); IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr);
IpcHandler.IpcCall( IpcHandler.IpcCall(Ns, Process, Memory, Session, Cmd, CmdPtr);
Ns,
Process,
Memory,
Session,
Cmd,
CmdPtr,
Handle);
Thread.Yield(); Thread.Yield();

View file

@ -39,7 +39,7 @@ namespace Ryujinx.Core.OsHle.Svc
{ {
int Handle = (int)ThreadState.X0; int Handle = (int)ThreadState.X0;
HThread Thread = Process.HandleTable.GetData<HThread>(Handle); KThread Thread = Process.HandleTable.GetData<KThread>(Handle);
if (Thread != null) if (Thread != null)
{ {
@ -53,16 +53,18 @@ namespace Ryujinx.Core.OsHle.Svc
private void SvcExitThread(AThreadState ThreadState) private void SvcExitThread(AThreadState ThreadState)
{ {
HThread CurrThread = Process.GetThread(ThreadState.Tpidr); KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
CurrThread.Thread.StopExecution(); CurrThread.Thread.StopExecution();
CurrThread.Handle.Set();
} }
private void SvcSleepThread(AThreadState ThreadState) private void SvcSleepThread(AThreadState ThreadState)
{ {
ulong NanoSecs = ThreadState.X0; ulong NanoSecs = ThreadState.X0;
HThread CurrThread = Process.GetThread(ThreadState.Tpidr); KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
if (NanoSecs == 0) if (NanoSecs == 0)
{ {
@ -78,7 +80,7 @@ namespace Ryujinx.Core.OsHle.Svc
{ {
int Handle = (int)ThreadState.X1; int Handle = (int)ThreadState.X1;
HThread Thread = Process.HandleTable.GetData<HThread>(Handle); KThread Thread = Process.HandleTable.GetData<KThread>(Handle);
if (Thread != null) if (Thread != null)
{ {
@ -91,10 +93,10 @@ namespace Ryujinx.Core.OsHle.Svc
private void SvcSetThreadPriority(AThreadState ThreadState) private void SvcSetThreadPriority(AThreadState ThreadState)
{ {
int Handle = (int)ThreadState.X1;
int Prio = (int)ThreadState.X0; int Prio = (int)ThreadState.X0;
int Handle = (int)ThreadState.X1;
HThread Thread = Process.HandleTable.GetData<HThread>(Handle); KThread Thread = Process.HandleTable.GetData<KThread>(Handle);
if (Thread != null) if (Thread != null)
{ {
@ -117,7 +119,7 @@ namespace Ryujinx.Core.OsHle.Svc
{ {
int Handle = (int)ThreadState.X0; int Handle = (int)ThreadState.X0;
HThread Thread = Process.HandleTable.GetData<HThread>(Handle); KThread Thread = Process.HandleTable.GetData<KThread>(Handle);
if (Thread != null) if (Thread != null)
{ {

View file

@ -13,7 +13,7 @@ namespace Ryujinx.Core.OsHle.Svc
long MutexAddress = (long)ThreadState.X1; long MutexAddress = (long)ThreadState.X1;
int RequestingThreadHandle = (int)ThreadState.X2; int RequestingThreadHandle = (int)ThreadState.X2;
HThread RequestingThread = Process.HandleTable.GetData<HThread>(RequestingThreadHandle); KThread RequestingThread = Process.HandleTable.GetData<KThread>(RequestingThreadHandle);
Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle); Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
@ -43,7 +43,7 @@ namespace Ryujinx.Core.OsHle.Svc
int ThreadHandle = (int)ThreadState.X2; int ThreadHandle = (int)ThreadState.X2;
long Timeout = (long)ThreadState.X3; long Timeout = (long)ThreadState.X3;
HThread Thread = Process.HandleTable.GetData<HThread>(ThreadHandle); KThread Thread = Process.HandleTable.GetData<KThread>(ThreadHandle);
Mutex M = new Mutex(Process, MutexAddress, ThreadHandle); Mutex M = new Mutex(Process, MutexAddress, ThreadHandle);
@ -72,7 +72,7 @@ namespace Ryujinx.Core.OsHle.Svc
long CondVarAddress = (long)ThreadState.X0; long CondVarAddress = (long)ThreadState.X0;
int Count = (int)ThreadState.X1; int Count = (int)ThreadState.X1;
HThread CurrThread = Process.GetThread(ThreadState.Tpidr); KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv)) if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
{ {

View file

@ -1,7 +1,6 @@
using ChocolArm64.Memory; using ChocolArm64.Memory;
using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Gal;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace Ryujinx.Graphics.Gpu namespace Ryujinx.Graphics.Gpu
{ {
@ -46,24 +45,6 @@ namespace Ryujinx.Graphics.Gpu
} }
break; break;
case (NsGpuRegister)0x114:
uint BindId = GetRegister((NsGpuRegister)0x11c);
if (BindId == 0xd)
{
using (FileStream FS = new FileStream("D:\\macro.bin", FileMode.Create))
{
BinaryWriter Writer = new BinaryWriter(FS);
foreach (int arg in Entry.Arguments)
{
Writer.Write(arg);
}
}
}
//System.Console.WriteLine("macro bind " + Entry.Arguments[0].ToString("x8"));
break;
case NsGpuRegister._3dVertexArray0Fetch: case NsGpuRegister._3dVertexArray0Fetch:
SendVertexBuffers(Memory); SendVertexBuffers(Memory);
break; break;