aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-06-11 14:58:30 -0300
committerGitHub <noreply@github.com>2022-06-11 14:58:30 -0300
commit70895bdb04c51e92b4d84946c66c122f9d54a73f (patch)
treee0dfa460afe48ce343ae94ab66125f4a0b7de5b4
parent830cbf91bb8766e6347291bdff765a8a4e8c95b8 (diff)
Allow concurrent BSD EventFd read/write (#3385)1.1.145
-rw-r--r--Ryujinx.HLE/HOS/Horizon.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs5
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs15
-rw-r--r--Ryujinx.HLE/HOS/Services/ServerBase.cs38
-rw-r--r--Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs9
5 files changed, 55 insertions, 14 deletions
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index b93ebc03..2e64542e 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -309,7 +309,7 @@ namespace Ryujinx.HLE.HOS
// only then doing connections to SM is safe.
SmServer.InitDone.WaitOne();
- BsdServer = new ServerBase(KernelContext, "BsdServer");
+ BsdServer = new ServerBase(KernelContext, "BsdServer", null, 2);
AudRenServer = new ServerBase(KernelContext, "AudioRendererServer");
AudOutServer = new ServerBase(KernelContext, "AudioOutServer");
FsServer = new ServerBase(KernelContext, "FsServer");
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index 0caeacad..d01c3e3b 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -735,11 +735,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ulong argsPtr,
ulong stackTop,
int priority,
- int cpuCore)
+ int cpuCore,
+ ThreadStart customThreadStart = null)
{
lock (_processLock)
{
- return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, null);
+ return thread.Initialize(entrypoint, argsPtr, stackTop, priority, cpuCore, this, ThreadType.User, customThreadStart);
}
}
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
index 179c7d4b..189e4a3e 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
@@ -2351,6 +2351,18 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
int priority,
int cpuCore)
{
+ return CreateThread(out handle, entrypoint, argsPtr, stackTop, priority, cpuCore, null);
+ }
+
+ public KernelResult CreateThread(
+ out int handle,
+ ulong entrypoint,
+ ulong argsPtr,
+ ulong stackTop,
+ int priority,
+ int cpuCore,
+ ThreadStart customThreadStart)
+ {
handle = 0;
KProcess currentProcess = KernelStatic.GetCurrentProcess();
@@ -2386,7 +2398,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
argsPtr,
stackTop,
priority,
- cpuCore);
+ cpuCore,
+ customThreadStart);
if (result == KernelResult.Success)
{
diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs
index 90783344..2aead42e 100644
--- a/Ryujinx.HLE/HOS/Services/ServerBase.cs
+++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Common;
@@ -38,15 +39,18 @@ namespace Ryujinx.HLE.HOS.Services
private readonly Dictionary<int, Func<IpcService>> _ports = new Dictionary<int, Func<IpcService>>();
public ManualResetEvent InitDone { get; }
- public Func<IpcService> SmObjectFactory { get; }
public string Name { get; }
+ public Func<IpcService> SmObjectFactory { get; }
+
+ private int _threadCount;
- public ServerBase(KernelContext context, string name, Func<IpcService> smObjectFactory = null)
+ public ServerBase(KernelContext context, string name, Func<IpcService> smObjectFactory = null, int threadCount = 1)
{
InitDone = new ManualResetEvent(false);
+ _context = context;
Name = name;
SmObjectFactory = smObjectFactory;
- _context = context;
+ _threadCount = threadCount;
const ProcessCreationFlags flags =
ProcessCreationFlags.EnableAslr |
@@ -56,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Services
ProcessCreationInfo creationInfo = new ProcessCreationInfo("Service", 1, 0, 0x8000000, 1, flags, 0, 0);
- KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, ServerLoop);
+ KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, Main);
}
private void AddPort(int serverPortHandle, Func<IpcService> objectFactory)
@@ -80,6 +84,32 @@ namespace Ryujinx.HLE.HOS.Services
_sessions.Add(serverSessionHandle, obj);
}
+ private void Main()
+ {
+ for (int i = 1; i < _threadCount; i++)
+ {
+ KernelResult result = _context.Syscall.CreateThread(out int threadHandle, 0UL, 0UL, 0UL, 44, 3, ServerLoop);
+
+ if (result == KernelResult.Success)
+ {
+ result = _context.Syscall.StartThread(threadHandle);
+
+ if (result != KernelResult.Success)
+ {
+ Logger.Error?.Print(LogClass.Service, $"Failed to start thread on {Name}: {result}");
+ }
+
+ _context.Syscall.CloseHandle(threadHandle);
+ }
+ else
+ {
+ Logger.Error?.Print(LogClass.Service, $"Failed to create thread on {Name}: {result}");
+ }
+ }
+
+ ServerLoop();
+ }
+
private void ServerLoop()
{
_selfProcess = KernelStatic.GetCurrentProcess();
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
index e92b42ef..ea63e842 100644
--- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
@@ -8,7 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
private ulong _value;
private readonly EventFdFlags _flags;
- private AutoResetEvent _event;
private object _lock = new object();
@@ -21,7 +20,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
_value = value;
_flags = flags;
- _event = new AutoResetEvent(false);
WriteEvent = new ManualResetEvent(true);
ReadEvent = new ManualResetEvent(true);
@@ -31,7 +29,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
public void Dispose()
{
- _event.Dispose();
WriteEvent.Dispose();
ReadEvent.Dispose();
}
@@ -57,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
while (_value == 0)
{
- _event.WaitOne();
+ Monitor.Wait(_lock);
}
}
else
@@ -106,7 +103,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
if (Blocking)
{
- _event.WaitOne();
+ Monitor.Wait(_lock);
}
else
{
@@ -119,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
writeSize = sizeof(ulong);
_value += count;
- _event.Set();
+ Monitor.Pulse(_lock);
WriteEvent.Set();