mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2025-09-19 11:07:53 -05:00
Made initial implementation of the thread scheduler, refactor Svc to avoid passing many arguments
This commit is contained in:
@@ -7,55 +7,50 @@ namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
partial class SvcHandler
|
||||
{
|
||||
private delegate void SvcFunc(Switch Ns, ARegisters Registers, AMemory Memory);
|
||||
private delegate void SvcFunc(ARegisters Registers);
|
||||
|
||||
private Dictionary<int, SvcFunc> SvcFuncs = new Dictionary<int, SvcFunc>()
|
||||
{
|
||||
{ 0x01, SvcSetHeapSize },
|
||||
{ 0x03, SvcSetMemoryAttribute },
|
||||
{ 0x04, SvcMapMemory },
|
||||
{ 0x06, SvcQueryMemory },
|
||||
{ 0x08, SvcCreateThread },
|
||||
{ 0x09, SvcStartThread },
|
||||
{ 0x0b, SvcSleepThread },
|
||||
{ 0x0c, SvcGetThreadPriority },
|
||||
{ 0x13, SvcMapSharedMemory },
|
||||
{ 0x14, SvcUnmapSharedMemory },
|
||||
{ 0x15, SvcCreateTransferMemory },
|
||||
{ 0x16, SvcCloseHandle },
|
||||
{ 0x17, SvcResetSignal },
|
||||
{ 0x18, SvcWaitSynchronization },
|
||||
{ 0x1a, SvcArbitrateLock },
|
||||
{ 0x1b, SvcArbitrateUnlock },
|
||||
{ 0x1c, SvcWaitProcessWideKeyAtomic },
|
||||
{ 0x1d, SvcSignalProcessWideKey },
|
||||
{ 0x1e, SvcGetSystemTick },
|
||||
{ 0x1f, SvcConnectToNamedPort },
|
||||
{ 0x21, SvcSendSyncRequest },
|
||||
{ 0x22, SvcSendSyncRequestWithUserBuffer },
|
||||
{ 0x26, SvcBreak },
|
||||
{ 0x27, SvcOutputDebugString },
|
||||
{ 0x29, SvcGetInfo }
|
||||
};
|
||||
|
||||
enum SvcResult
|
||||
{
|
||||
Success = 0,
|
||||
ErrBadHandle = 0xe401,
|
||||
ErrTimeout = 0xea01,
|
||||
ErrBadInfo = 0xf001,
|
||||
ErrBadIpcReq = 0xf601
|
||||
}
|
||||
private Dictionary<int, SvcFunc> SvcFuncs;
|
||||
|
||||
private Switch Ns;
|
||||
private Process Process;
|
||||
private AMemory Memory;
|
||||
|
||||
private static Random Rng;
|
||||
|
||||
public SvcHandler(Switch Ns, AMemory Memory)
|
||||
public SvcHandler(Switch Ns, Process Process)
|
||||
{
|
||||
this.Ns = Ns;
|
||||
this.Memory = Memory;
|
||||
SvcFuncs = new Dictionary<int, SvcFunc>()
|
||||
{
|
||||
{ 0x01, SvcSetHeapSize },
|
||||
{ 0x03, SvcSetMemoryAttribute },
|
||||
{ 0x04, SvcMapMemory },
|
||||
{ 0x06, SvcQueryMemory },
|
||||
{ 0x08, SvcCreateThread },
|
||||
{ 0x09, SvcStartThread },
|
||||
{ 0x0b, SvcSleepThread },
|
||||
{ 0x0c, SvcGetThreadPriority },
|
||||
{ 0x13, SvcMapSharedMemory },
|
||||
{ 0x14, SvcUnmapSharedMemory },
|
||||
{ 0x15, SvcCreateTransferMemory },
|
||||
{ 0x16, SvcCloseHandle },
|
||||
{ 0x17, SvcResetSignal },
|
||||
{ 0x18, SvcWaitSynchronization },
|
||||
{ 0x1a, SvcArbitrateLock },
|
||||
{ 0x1b, SvcArbitrateUnlock },
|
||||
{ 0x1c, SvcWaitProcessWideKeyAtomic },
|
||||
{ 0x1d, SvcSignalProcessWideKey },
|
||||
{ 0x1e, SvcGetSystemTick },
|
||||
{ 0x1f, SvcConnectToNamedPort },
|
||||
{ 0x21, SvcSendSyncRequest },
|
||||
{ 0x22, SvcSendSyncRequestWithUserBuffer },
|
||||
{ 0x26, SvcBreak },
|
||||
{ 0x27, SvcOutputDebugString },
|
||||
{ 0x29, SvcGetInfo }
|
||||
};
|
||||
|
||||
this.Ns = Ns;
|
||||
this.Process = Process;
|
||||
this.Memory = Process.Memory;
|
||||
}
|
||||
|
||||
static SvcHandler()
|
||||
@@ -69,9 +64,11 @@ namespace Ryujinx.OsHle.Svc
|
||||
|
||||
if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func))
|
||||
{
|
||||
Logging.Trace($"{Func.Method.Name} called.");
|
||||
Func(Ns, Registers, Memory);
|
||||
Logging.Trace($"{Func.Method.Name} ended.");
|
||||
Logging.Trace($"(Thread {Registers.ThreadId}) {Func.Method.Name} called.");
|
||||
|
||||
Func(Registers);
|
||||
|
||||
Logging.Trace($"(Thread {Registers.ThreadId}) {Func.Method.Name} ended.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -6,7 +6,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
partial class SvcHandler
|
||||
{
|
||||
private static void SvcSetHeapSize(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSetHeapSize(ARegisters Registers)
|
||||
{
|
||||
uint Size = (uint)Registers.X1;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X1 = (ulong)Memory.Manager.HeapAddr;
|
||||
}
|
||||
|
||||
private static void SvcSetMemoryAttribute(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSetMemoryAttribute(ARegisters Registers)
|
||||
{
|
||||
long Position = (long)Registers.X0;
|
||||
long Size = (long)Registers.X1;
|
||||
@@ -28,7 +28,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcMapMemory(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcMapMemory(ARegisters Registers)
|
||||
{
|
||||
long Dst = (long)Registers.X0;
|
||||
long Src = (long)Registers.X1;
|
||||
@@ -39,7 +39,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcQueryMemory(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcQueryMemory(ARegisters Registers)
|
||||
{
|
||||
long InfoPtr = (long)Registers.X0;
|
||||
long Position = (long)Registers.X2;
|
||||
@@ -63,7 +63,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X1 = 0;
|
||||
}
|
||||
|
||||
private static void SvcMapSharedMemory(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcMapSharedMemory(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X0;
|
||||
long Position = (long)Registers.X1;
|
||||
@@ -87,7 +87,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
//TODO: Error codes.
|
||||
}
|
||||
|
||||
private static void SvcUnmapSharedMemory(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcUnmapSharedMemory(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X0;
|
||||
long Position = (long)Registers.X1;
|
||||
@@ -103,7 +103,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
//TODO: Error codes.
|
||||
}
|
||||
|
||||
private static void SvcCreateTransferMemory(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcCreateTransferMemory(ARegisters Registers)
|
||||
{
|
||||
long Position = (long)Registers.X1;
|
||||
long Size = (long)Registers.X2;
|
||||
|
11
Ryujinx/OsHle/Svc/SvcResult.cs
Normal file
11
Ryujinx/OsHle/Svc/SvcResult.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
enum SvcResult
|
||||
{
|
||||
Success = 0,
|
||||
ErrBadHandle = 0xe401,
|
||||
ErrTimeout = 0xea01,
|
||||
ErrBadInfo = 0xf001,
|
||||
ErrBadIpcReq = 0xf601
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
using ChocolArm64.Memory;
|
||||
using ChocolArm64.State;
|
||||
using Ryujinx.OsHle.Exceptions;
|
||||
using Ryujinx.OsHle.Handles;
|
||||
using Ryujinx.OsHle.Ipc;
|
||||
using System;
|
||||
@@ -8,7 +9,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
partial class SvcHandler
|
||||
{
|
||||
private static void SvcCloseHandle(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcCloseHandle(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X0;
|
||||
|
||||
@@ -17,7 +18,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcResetSignal(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcResetSignal(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X0;
|
||||
|
||||
@@ -26,7 +27,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcWaitSynchronization(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcWaitSynchronization(ARegisters Registers)
|
||||
{
|
||||
long HandlesPtr = (long)Registers.X0;
|
||||
int HandlesCount = (int)Registers.X2;
|
||||
@@ -34,15 +35,26 @@ namespace Ryujinx.OsHle.Svc
|
||||
|
||||
//TODO: Implement events.
|
||||
|
||||
//Logging.Info($"SvcWaitSynchronization Thread {Registers.ThreadId}");
|
||||
|
||||
if (Process.TryGetThread(Registers.Tpidr, out HThread Thread))
|
||||
{
|
||||
Process.Scheduler.Yield(Thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error($"Thread with TPIDR_EL0 0x{Registers.Tpidr:x16} not found!");
|
||||
}
|
||||
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcGetSystemTick(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcGetSystemTick(ARegisters Registers)
|
||||
{
|
||||
Registers.X0 = (ulong)Registers.CntpctEl0;
|
||||
}
|
||||
|
||||
private static void SvcConnectToNamedPort(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcConnectToNamedPort(ARegisters Registers)
|
||||
{
|
||||
long StackPtr = (long)Registers.X0;
|
||||
long NamePtr = (long)Registers.X1;
|
||||
@@ -58,23 +70,23 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcSendSyncRequest(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSendSyncRequest(ARegisters Registers)
|
||||
{
|
||||
SendSyncRequest(Ns, Registers, Memory, false);
|
||||
SendSyncRequest(Registers, false);
|
||||
}
|
||||
|
||||
private static void SvcSendSyncRequestWithUserBuffer(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSendSyncRequestWithUserBuffer(ARegisters Registers)
|
||||
{
|
||||
SendSyncRequest(Ns, Registers, Memory, true);
|
||||
SendSyncRequest(Registers, true);
|
||||
}
|
||||
|
||||
private static void SendSyncRequest(Switch Ns, ARegisters Registers, AMemory Memory, bool IsUser)
|
||||
private void SendSyncRequest(ARegisters Registers, bool UserBuffer)
|
||||
{
|
||||
long CmdPtr = Registers.Tpidr;
|
||||
long Size = 0x100;
|
||||
int Handle = 0;
|
||||
|
||||
if (IsUser)
|
||||
if (UserBuffer)
|
||||
{
|
||||
CmdPtr = (long)Registers.X0;
|
||||
Size = (long)Registers.X1;
|
||||
@@ -105,16 +117,16 @@ namespace Ryujinx.OsHle.Svc
|
||||
}
|
||||
}
|
||||
|
||||
private static void SvcBreak(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcBreak(ARegisters Registers)
|
||||
{
|
||||
long Reason = (long)Registers.X0;
|
||||
long Unknown = (long)Registers.X1;
|
||||
long Info = (long)Registers.X2;
|
||||
|
||||
throw new Exception($"SvcBreak: {Reason} {Unknown} {Info}");
|
||||
throw new GuestBrokeExecutionException();
|
||||
}
|
||||
|
||||
private static void SvcOutputDebugString(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcOutputDebugString(ARegisters Registers)
|
||||
{
|
||||
long Position = (long)Registers.X0;
|
||||
long Size = (long)Registers.X1;
|
||||
@@ -126,7 +138,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcGetInfo(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcGetInfo(ARegisters Registers)
|
||||
{
|
||||
long StackPtr = (long)Registers.X0;
|
||||
int InfoType = (int)Registers.X1;
|
||||
@@ -148,8 +160,8 @@ namespace Ryujinx.OsHle.Svc
|
||||
case 3: Registers.X1 = GetMapRegionSize(); break;
|
||||
case 4: Registers.X1 = GetHeapRegionBaseAddr(); break;
|
||||
case 5: Registers.X1 = GetHeapRegionSize(); break;
|
||||
case 6: Registers.X1 = GetTotalMem(Memory); break;
|
||||
case 7: Registers.X1 = GetUsedMem(Memory); break;
|
||||
case 6: Registers.X1 = GetTotalMem(); break;
|
||||
case 7: Registers.X1 = GetUsedMem(); break;
|
||||
case 11: Registers.X1 = GetRnd64(); break;
|
||||
case 12: Registers.X1 = GetAddrSpaceBaseAddr(); break;
|
||||
case 13: Registers.X1 = GetAddrSpaceSize(); break;
|
||||
@@ -162,47 +174,47 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static ulong GetTotalMem(AMemory Memory)
|
||||
private ulong GetTotalMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetTotalMemorySize();
|
||||
}
|
||||
|
||||
private static ulong GetUsedMem(AMemory Memory)
|
||||
private ulong GetUsedMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetUsedMemorySize();
|
||||
}
|
||||
|
||||
private static ulong GetRnd64()
|
||||
private ulong GetRnd64()
|
||||
{
|
||||
return (ulong)Rng.Next() + ((ulong)Rng.Next() << 32);
|
||||
}
|
||||
|
||||
private static ulong GetAddrSpaceBaseAddr()
|
||||
private ulong GetAddrSpaceBaseAddr()
|
||||
{
|
||||
return 0x08000000;
|
||||
}
|
||||
|
||||
private static ulong GetAddrSpaceSize()
|
||||
private ulong GetAddrSpaceSize()
|
||||
{
|
||||
return AMemoryMgr.AddrSize - GetAddrSpaceBaseAddr();
|
||||
}
|
||||
|
||||
private static ulong GetMapRegionBaseAddr()
|
||||
private ulong GetMapRegionBaseAddr()
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
|
||||
private static ulong GetMapRegionSize()
|
||||
private ulong GetMapRegionSize()
|
||||
{
|
||||
return 0x40000000;
|
||||
}
|
||||
|
||||
private static ulong GetHeapRegionBaseAddr()
|
||||
private ulong GetHeapRegionBaseAddr()
|
||||
{
|
||||
return GetMapRegionBaseAddr() + GetMapRegionSize();
|
||||
}
|
||||
|
||||
private static ulong GetHeapRegionSize()
|
||||
private ulong GetHeapRegionSize()
|
||||
{
|
||||
return 0x40000000;
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
using ChocolArm64.Memory;
|
||||
using ChocolArm64.State;
|
||||
using Ryujinx.OsHle.Handles;
|
||||
using System.Threading;
|
||||
@@ -7,7 +6,7 @@ namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
partial class SvcHandler
|
||||
{
|
||||
private static void SvcCreateThread(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcCreateThread(ARegisters Registers)
|
||||
{
|
||||
long EntryPoint = (long)Registers.X1;
|
||||
long ArgsPtr = (long)Registers.X2;
|
||||
@@ -17,12 +16,17 @@ namespace Ryujinx.OsHle.Svc
|
||||
|
||||
if (Ns.Os.TryGetProcess(Registers.ProcessId, out Process Process))
|
||||
{
|
||||
if (ProcessorId == -2)
|
||||
{
|
||||
ProcessorId = 0;
|
||||
}
|
||||
|
||||
int Handle = Process.MakeThread(
|
||||
EntryPoint,
|
||||
StackTop,
|
||||
ArgsPtr,
|
||||
Priority,
|
||||
ProcessorId);
|
||||
ProcessorId);
|
||||
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
Registers.X1 = (ulong)Handle;
|
||||
@@ -31,15 +35,15 @@ namespace Ryujinx.OsHle.Svc
|
||||
//TODO: Error codes.
|
||||
}
|
||||
|
||||
private static void SvcStartThread(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcStartThread(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X0;
|
||||
|
||||
HThread HndData = Ns.Os.Handles.GetData<HThread>(Handle);
|
||||
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
|
||||
|
||||
if (HndData != null)
|
||||
if (Thread != null)
|
||||
{
|
||||
HndData.Thread.Execute();
|
||||
Process.Scheduler.StartThread(Thread);
|
||||
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
@@ -47,29 +51,31 @@ namespace Ryujinx.OsHle.Svc
|
||||
//TODO: Error codes.
|
||||
}
|
||||
|
||||
private static void SvcSleepThread(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSleepThread(ARegisters Registers)
|
||||
{
|
||||
ulong NanoSecs = Registers.X0;
|
||||
|
||||
if (NanoSecs == 0)
|
||||
if (Process.TryGetThread(Registers.Tpidr, out HThread CurrThread))
|
||||
{
|
||||
Thread.Yield();
|
||||
Process.Scheduler.Yield(CurrThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep((int)(NanoSecs / 1000000));
|
||||
Logging.Error($"Thread with TPIDR_EL0 0x{Registers.Tpidr:x16} not found!");
|
||||
}
|
||||
|
||||
Thread.Sleep((int)(NanoSecs / 1000000));
|
||||
}
|
||||
|
||||
private static void SvcGetThreadPriority(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcGetThreadPriority(ARegisters Registers)
|
||||
{
|
||||
int Handle = (int)Registers.X1;
|
||||
|
||||
HThread HndData = Ns.Os.Handles.GetData<HThread>(Handle);
|
||||
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
|
||||
|
||||
if (HndData != null)
|
||||
if (Thread != null)
|
||||
{
|
||||
Registers.X1 = (ulong)HndData.Thread.Priority;
|
||||
Registers.X1 = (ulong)Thread.Priority;
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using ChocolArm64;
|
||||
using ChocolArm64.Memory;
|
||||
using ChocolArm64.State;
|
||||
using Ryujinx.OsHle.Handles;
|
||||
|
||||
@@ -7,27 +6,24 @@ namespace Ryujinx.OsHle.Svc
|
||||
{
|
||||
partial class SvcHandler
|
||||
{
|
||||
private static void SvcArbitrateLock(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcArbitrateLock(ARegisters Registers)
|
||||
{
|
||||
int OwnerThreadHandle = (int)Registers.X0;
|
||||
long MutexAddress = (long)Registers.X1;
|
||||
int RequestingThreadHandle = (int)Registers.X2;
|
||||
|
||||
AThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle).Thread;
|
||||
HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle);
|
||||
|
||||
Mutex M = new Mutex(Memory, MutexAddress);
|
||||
Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
|
||||
|
||||
M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
|
||||
|
||||
//FIXME
|
||||
//M.WaitForLock(RequestingThread, RequestingThreadHandle);
|
||||
|
||||
Memory.WriteInt32(MutexAddress, 0);
|
||||
M.WaitForLock(RequestingThread, RequestingThreadHandle);
|
||||
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcArbitrateUnlock(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcArbitrateUnlock(ARegisters Registers)
|
||||
{
|
||||
long MutexAddress = (long)Registers.X0;
|
||||
|
||||
@@ -39,39 +35,36 @@ namespace Ryujinx.OsHle.Svc
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcWaitProcessWideKeyAtomic(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcWaitProcessWideKeyAtomic(ARegisters Registers)
|
||||
{
|
||||
long MutexAddress = (long)Registers.X0;
|
||||
long CondVarAddress = (long)Registers.X1;
|
||||
int ThreadHandle = (int)Registers.X2;
|
||||
long Timeout = (long)Registers.X3;
|
||||
|
||||
AThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle).Thread;
|
||||
HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle);
|
||||
|
||||
if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
|
||||
{
|
||||
M.GiveUpLock(ThreadHandle);
|
||||
}
|
||||
|
||||
CondVar Signal = new CondVar(Memory, CondVarAddress, Timeout);
|
||||
CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);
|
||||
|
||||
Signal = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Signal);
|
||||
Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);
|
||||
|
||||
Signal.WaitForSignal(ThreadHandle);
|
||||
Cv.WaitForSignal(Thread);
|
||||
|
||||
M = new Mutex(Memory, MutexAddress);
|
||||
M = new Mutex(Process, MutexAddress, ThreadHandle);
|
||||
|
||||
M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
|
||||
|
||||
//FIXME
|
||||
//M.WaitForLock(Thread, ThreadHandle);
|
||||
|
||||
Memory.WriteInt32(MutexAddress, 0);
|
||||
M.WaitForLock(Thread, ThreadHandle);
|
||||
|
||||
Registers.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private static void SvcSignalProcessWideKey(Switch Ns, ARegisters Registers, AMemory Memory)
|
||||
private void SvcSignalProcessWideKey(ARegisters Registers)
|
||||
{
|
||||
long CondVarAddress = (long)Registers.X0;
|
||||
int Count = (int)Registers.X1;
|
||||
|
Reference in New Issue
Block a user