IPC refactor part 3+4: New server HIPC message processor (#4188)
* IPC refactor part 3 + 4: New server HIPC message processor with source generator based serialization * Make types match on calls to AlignUp/AlignDown * Formatting * Address some PR feedback * Move BitfieldExtensions to Ryujinx.Common.Utilities and consolidate implementations * Rename Reader/Writer to SpanReader/SpanWriter and move to Ryujinx.Common.Memory * Implement EventType * Address more PR feedback * Log request processing errors since they are not normal * Rename waitable to multiwait and add missing lock * PR feedback * Ac_K PR feedback
This commit is contained in:
parent
c6a139a6e7
commit
08831eecf7
213 changed files with 9762 additions and 1010 deletions
33
Ryujinx.Horizon.Common/ISyscallApi.cs
Normal file
33
Ryujinx.Horizon.Common/ISyscallApi.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public interface ISyscallApi
|
||||
{
|
||||
Result SetHeapSize(out ulong address, ulong size);
|
||||
|
||||
void SleepThread(long timeout);
|
||||
|
||||
Result CloseHandle(int handle);
|
||||
|
||||
Result WaitSynchronization(out int handleIndex, ReadOnlySpan<int> handles, long timeout);
|
||||
Result CancelSynchronization(int handle);
|
||||
|
||||
Result GetProcessId(out ulong pid, int handle);
|
||||
|
||||
Result ConnectToNamedPort(out int handle, string name);
|
||||
Result SendSyncRequest(int handle);
|
||||
Result CreateSession(out int serverSessionHandle, out int clientSessionHandle, bool isLight, string name);
|
||||
Result AcceptSession(out int sessionHandle, int portHandle);
|
||||
Result ReplyAndReceive(out int handleIndex, ReadOnlySpan<int> handles, int replyTargetHandle, long timeout);
|
||||
|
||||
Result CreateEvent(out int writableHandle, out int readableHandle);
|
||||
Result SignalEvent(int handle);
|
||||
Result ClearEvent(int handle);
|
||||
Result ResetSignal(int handle);
|
||||
|
||||
Result CreatePort(out int serverPortHandle, out int clientPortHandle, int maxSessions, bool isLight, string name);
|
||||
Result ManageNamedPort(out int handle, string name, int maxSessions);
|
||||
Result ConnectToPort(out int clientSessionHandle, int clientPortHandle);
|
||||
}
|
||||
}
|
11
Ryujinx.Horizon.Common/IThreadContext.cs
Normal file
11
Ryujinx.Horizon.Common/IThreadContext.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public interface IThreadContext
|
||||
{
|
||||
bool Running { get; }
|
||||
|
||||
ulong TlsAddress { get; }
|
||||
|
||||
ulong GetX(int index);
|
||||
}
|
||||
}
|
23
Ryujinx.Horizon.Common/InvalidResultException.cs
Normal file
23
Ryujinx.Horizon.Common/InvalidResultException.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public class InvalidResultException : Exception
|
||||
{
|
||||
public InvalidResultException()
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidResultException(Result result) : base($"Unexpected result code {result} returned.")
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidResultException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidResultException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
39
Ryujinx.Horizon.Common/KernelResult.cs
Normal file
39
Ryujinx.Horizon.Common/KernelResult.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public static class KernelResult
|
||||
{
|
||||
private const int ModuleId = 1;
|
||||
|
||||
public static Result SessionCountExceeded => new Result(ModuleId, 7);
|
||||
public static Result InvalidCapability => new Result(ModuleId, 14);
|
||||
public static Result ThreadNotStarted => new Result(ModuleId, 57);
|
||||
public static Result ThreadTerminating => new Result(ModuleId, 59);
|
||||
public static Result InvalidSize => new Result(ModuleId, 101);
|
||||
public static Result InvalidAddress => new Result(ModuleId, 102);
|
||||
public static Result OutOfResource => new Result(ModuleId, 103);
|
||||
public static Result OutOfMemory => new Result(ModuleId, 104);
|
||||
public static Result HandleTableFull => new Result(ModuleId, 105);
|
||||
public static Result InvalidMemState => new Result(ModuleId, 106);
|
||||
public static Result InvalidPermission => new Result(ModuleId, 108);
|
||||
public static Result InvalidMemRange => new Result(ModuleId, 110);
|
||||
public static Result InvalidPriority => new Result(ModuleId, 112);
|
||||
public static Result InvalidCpuCore => new Result(ModuleId, 113);
|
||||
public static Result InvalidHandle => new Result(ModuleId, 114);
|
||||
public static Result UserCopyFailed => new Result(ModuleId, 115);
|
||||
public static Result InvalidCombination => new Result(ModuleId, 116);
|
||||
public static Result TimedOut => new Result(ModuleId, 117);
|
||||
public static Result Cancelled => new Result(ModuleId, 118);
|
||||
public static Result MaximumExceeded => new Result(ModuleId, 119);
|
||||
public static Result InvalidEnumValue => new Result(ModuleId, 120);
|
||||
public static Result NotFound => new Result(ModuleId, 121);
|
||||
public static Result InvalidThread => new Result(ModuleId, 122);
|
||||
public static Result PortRemoteClosed => new Result(ModuleId, 123);
|
||||
public static Result InvalidState => new Result(ModuleId, 125);
|
||||
public static Result ReservedValue => new Result(ModuleId, 126);
|
||||
public static Result PortClosed => new Result(ModuleId, 131);
|
||||
public static Result ResLimitExceeded => new Result(ModuleId, 132);
|
||||
public static Result ReceiveListBroken => new Result(ModuleId, 258);
|
||||
public static Result OutOfVaSpace => new Result(ModuleId, 259);
|
||||
public static Result CmdBufferTooSmall => new Result(ModuleId, 260);
|
||||
}
|
||||
}
|
19
Ryujinx.Horizon.Common/OnScopeExit.cs
Normal file
19
Ryujinx.Horizon.Common/OnScopeExit.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public struct OnScopeExit : IDisposable
|
||||
{
|
||||
private readonly Action _action;
|
||||
|
||||
public OnScopeExit(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
}
|
118
Ryujinx.Horizon.Common/Result.cs
Normal file
118
Ryujinx.Horizon.Common/Result.cs
Normal file
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Horizon.Common
|
||||
{
|
||||
public struct Result : IEquatable<Result>
|
||||
{
|
||||
private const int ModuleBits = 9;
|
||||
private const int DescriptionBits = 13;
|
||||
private const int ModuleMax = 1 << ModuleBits;
|
||||
private const int DescriptionMax = 1 << DescriptionBits;
|
||||
|
||||
public static Result Success { get; } = new Result(0, 0);
|
||||
|
||||
public int ErrorCode { get; }
|
||||
|
||||
public bool IsSuccess => ErrorCode == 0;
|
||||
public bool IsFailure => ErrorCode != 0;
|
||||
|
||||
public int Module => ErrorCode & (ModuleMax - 1);
|
||||
public int Description => (ErrorCode >> ModuleBits) & (DescriptionMax - 1);
|
||||
|
||||
public string PrintableResult => $"{2000 + Module:D4}-{Description:D4}";
|
||||
|
||||
public Result(int module, int description)
|
||||
{
|
||||
if ((uint)module >= ModuleMax)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(module));
|
||||
}
|
||||
|
||||
if ((uint)description >= DescriptionMax)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(description));
|
||||
}
|
||||
|
||||
ErrorCode = module | (description << ModuleBits);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Result result && result.Equals(this);
|
||||
}
|
||||
|
||||
public bool Equals(Result other)
|
||||
{
|
||||
return other.ErrorCode == ErrorCode;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
public static bool operator ==(Result lhs, Result rhs)
|
||||
{
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
public static bool operator !=(Result lhs, Result rhs)
|
||||
{
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
public bool InRange(int minInclusive, int maxInclusive)
|
||||
{
|
||||
return (uint)(Description - minInclusive) <= (uint)(maxInclusive - minInclusive);
|
||||
}
|
||||
|
||||
public void AbortOnSuccess()
|
||||
{
|
||||
if (IsSuccess)
|
||||
{
|
||||
ThrowInvalidResult();
|
||||
}
|
||||
}
|
||||
|
||||
public void AbortOnFailure()
|
||||
{
|
||||
if (this == KernelResult.ThreadTerminating)
|
||||
{
|
||||
throw new ThreadTerminatedException();
|
||||
}
|
||||
|
||||
AbortUnless(Success);
|
||||
}
|
||||
|
||||
public void AbortUnless(Result result)
|
||||
{
|
||||
if (this != result)
|
||||
{
|
||||
ThrowInvalidResult();
|
||||
}
|
||||
}
|
||||
|
||||
public void AbortUnless(Result result, Result result2)
|
||||
{
|
||||
if (this != result && this != result2)
|
||||
{
|
||||
ThrowInvalidResult();
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowInvalidResult()
|
||||
{
|
||||
throw new InvalidResultException(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (ResultNames.TryGet(ErrorCode, out string name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
return PrintableResult;
|
||||
}
|
||||
}
|
||||
}
|
1701
Ryujinx.Horizon.Common/ResultNames.cs
Normal file
1701
Ryujinx.Horizon.Common/ResultNames.cs
Normal file
File diff suppressed because it is too large
Load diff
11
Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj
Normal file
11
Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj
Normal file
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue