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:
gdkchan 2023-01-04 19:15:45 -03:00 committed by GitHub
parent c6a139a6e7
commit 08831eecf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
213 changed files with 9762 additions and 1010 deletions

View file

@ -5,6 +5,7 @@ using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Horizon.Common;
using Ryujinx.Memory;
using System;
using System.Collections.Generic;
@ -116,7 +117,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
Debugger = new HleProcessDebugger(this);
}
public KernelResult InitializeKip(
public Result InitializeKip(
ProcessCreationInfo creationInfo,
ReadOnlySpan<int> capabilities,
KPageList pageList,
@ -151,7 +152,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
? KernelContext.LargeMemoryBlockSlabManager
: KernelContext.SmallMemoryBlockSlabManager;
KernelResult result = MemoryManager.InitializeForProcess(
Result result = MemoryManager.InitializeForProcess(
addrSpaceType,
aslrEnabled,
!aslrEnabled,
@ -160,7 +161,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
codeSize,
slabManager);
if (result != KernelResult.Success)
if (result != Result.Success)
{
return result;
}
@ -172,14 +173,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = MemoryManager.MapPages(codeAddress, pageList, MemoryState.CodeStatic, KMemoryPermission.None);
if (result != KernelResult.Success)
if (result != Result.Success)
{
return result;
}
result = Capabilities.InitializeForKernel(capabilities, MemoryManager);
if (result != KernelResult.Success)
if (result != Result.Success)
{
return result;
}
@ -187,7 +188,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return ParseProcessInfo(creationInfo);
}
public KernelResult Initialize(
public Result Initialize(
ProcessCreationInfo creationInfo,
ReadOnlySpan<int> capabilities,
KResourceLimit resourceLimit,
@ -255,7 +256,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ulong codeSize = codePagesCount * KPageTableBase.PageSize;
KernelResult result = MemoryManager.InitializeForProcess(
Result result = MemoryManager.InitializeForProcess(
addrSpaceType,
aslrEnabled,
!aslrEnabled,
@ -264,7 +265,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
codeSize,
slabManager);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -284,7 +285,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
MemoryState.CodeStatic,
KMemoryPermission.None);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -293,7 +294,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = Capabilities.InitializeForUser(capabilities, MemoryManager);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -302,7 +303,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = ParseProcessInfo(creationInfo);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
}
@ -310,7 +311,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo)
private Result ParseProcessInfo(ProcessCreationInfo creationInfo)
{
// Ensure that the current kernel version is equal or above to the minimum required.
uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19;
@ -334,9 +335,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
KernelResult result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress);
Result result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress);
if (result != KernelResult.Success)
if (result != Result.Success)
{
return result;
}
@ -378,14 +379,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
GenerateRandomEntropy();
return KernelResult.Success;
return Result.Success;
}
public KernelResult AllocateThreadLocalStorage(out ulong address)
public Result AllocateThreadLocalStorage(out ulong address)
{
KernelContext.CriticalSection.Enter();
KernelResult result;
Result result;
if (_freeTlsPages.Count > 0)
{
@ -404,14 +405,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_fullTlsPages.Add(pageInfo.PageVirtualAddress, pageInfo);
}
result = KernelResult.Success;
result = Result.Success;
}
else
{
// Otherwise, we need to create a new one.
result = AllocateTlsPage(out KTlsPageInfo pageInfo);
if (result == KernelResult.Success)
if (result == Result.Success)
{
if (!pageInfo.TryGetFreePage(out address))
{
@ -431,7 +432,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
private KernelResult AllocateTlsPage(out KTlsPageInfo pageInfo)
private Result AllocateTlsPage(out KTlsPageInfo pageInfo)
{
pageInfo = default;
@ -445,7 +446,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ulong regionPagesCount = regionSize / KPageTableBase.PageSize;
KernelResult result = MemoryManager.MapPages(
Result result = MemoryManager.MapPages(
1,
KPageTableBase.PageSize,
tlsPagePa,
@ -456,7 +457,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
KMemoryPermission.ReadAndWrite,
out ulong tlsPageVa);
if (result != KernelResult.Success)
if (result != Result.Success)
{
KernelContext.UserSlabHeapPages.Free(tlsPagePa);
}
@ -470,13 +471,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
public KernelResult FreeThreadLocalStorage(ulong tlsSlotAddr)
public Result FreeThreadLocalStorage(ulong tlsSlotAddr)
{
ulong tlsPageAddr = BitUtils.AlignDown<ulong>(tlsSlotAddr, KPageTableBase.PageSize);
KernelContext.CriticalSection.Enter();
KernelResult result = KernelResult.Success;
Result result = Result.Success;
KTlsPageInfo pageInfo;
@ -506,7 +507,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
FreeTlsPage(pageInfo);
return KernelResult.Success;
return Result.Success;
}
}
@ -515,11 +516,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
private KernelResult FreeTlsPage(KTlsPageInfo pageInfo)
private Result FreeTlsPage(KTlsPageInfo pageInfo)
{
KernelResult result = MemoryManager.UnmapForKernel(pageInfo.PageVirtualAddress, 1, MemoryState.ThreadLocal);
Result result = MemoryManager.UnmapForKernel(pageInfo.PageVirtualAddress, 1, MemoryState.ThreadLocal);
if (result == KernelResult.Success)
if (result == Result.Success)
{
KernelContext.UserSlabHeapPages.Free(pageInfo.PagePhysicalAddress);
}
@ -532,7 +533,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
// TODO.
}
public KernelResult Start(int mainThreadPriority, ulong stackSize)
public Result Start(int mainThreadPriority, ulong stackSize)
{
lock (_processLock)
{
@ -580,7 +581,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
KernelResult result;
Result result;
KThread mainThread = null;
@ -627,7 +628,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
KMemoryPermission.ReadAndWrite,
out ulong stackBottom);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -643,7 +644,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = MemoryManager.SetHeapCapacity(heapCapacity);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -654,7 +655,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = HandleTable.Initialize(Capabilities.HandleTableSize);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -673,7 +674,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ThreadType.User,
_customThreadStart);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -682,7 +683,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);
if (result != KernelResult.Success)
if (result != Result.Success)
{
CleanUpForError();
@ -700,14 +701,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
result = mainThread.Start();
if (result != KernelResult.Success)
if (result != Result.Success)
{
SetState(oldState);
CleanUpForError();
}
if (result == KernelResult.Success)
if (result == Result.Success)
{
mainThread.IncrementReferenceCount();
}
@ -729,7 +730,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
public KernelResult InitializeThread(
public Result InitializeThread(
KThread thread,
ulong entrypoint,
ulong argsPtr,
@ -888,9 +889,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return _signaled;
}
public KernelResult Terminate()
public Result Terminate()
{
KernelResult result;
Result result;
bool shallTerminate = false;
@ -910,7 +911,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
shallTerminate = true;
}
result = KernelResult.Success;
result = Result.Success;
}
else
{
@ -1044,9 +1045,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
KernelContext.CriticalSection.Leave();
}
public KernelResult ClearIfNotExited()
public Result ClearIfNotExited()
{
KernelResult result;
Result result;
KernelContext.CriticalSection.Enter();
@ -1056,7 +1057,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
_signaled = false;
result = KernelResult.Success;
result = Result.Success;
}
else
{
@ -1107,7 +1108,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
protected override void Destroy() => Context.Dispose();
public KernelResult SetActivity(bool pause)
public Result SetActivity(bool pause)
{
KernelContext.CriticalSection.Enter();
@ -1154,7 +1155,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
KernelContext.CriticalSection.Leave();
return KernelResult.Success;
return Result.Success;
}
KernelContext.CriticalSection.Leave();