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
140
Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs
Normal file
140
Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs
Normal file
|
@ -0,0 +1,140 @@
|
|||
using Ryujinx.Horizon.Common;
|
||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||
{
|
||||
class DomainServiceObjectProcessor : ServerMessageProcessor
|
||||
{
|
||||
public const int MaximumObjects = 8;
|
||||
|
||||
private ServerMessageProcessor _implProcessor;
|
||||
private readonly ServerDomainBase _domain;
|
||||
private int _outObjectIdsOffset;
|
||||
private readonly int[] _inObjectIds;
|
||||
private readonly int[] _reservedObjectIds;
|
||||
private ServerMessageRuntimeMetadata _implMetadata;
|
||||
|
||||
private int InObjectsCount => _inObjectIds.Length;
|
||||
private int OutObjectsCount => _implMetadata.OutObjectsCount;
|
||||
private int ImplOutHeadersSize => _implMetadata.OutHeadersSize;
|
||||
private int ImplOutDataTotalSize => _implMetadata.OutDataSize + _implMetadata.OutHeadersSize;
|
||||
|
||||
public DomainServiceObjectProcessor(ServerDomainBase domain, int[] inObjectIds)
|
||||
{
|
||||
_domain = domain;
|
||||
_inObjectIds = inObjectIds;
|
||||
_reservedObjectIds = new int[MaximumObjects];
|
||||
}
|
||||
|
||||
public override void SetImplementationProcessor(ServerMessageProcessor impl)
|
||||
{
|
||||
if (_implProcessor == null)
|
||||
{
|
||||
_implProcessor = impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
_implProcessor.SetImplementationProcessor(impl);
|
||||
}
|
||||
|
||||
_implMetadata = _implProcessor.GetRuntimeMetadata();
|
||||
}
|
||||
|
||||
public override ServerMessageRuntimeMetadata GetRuntimeMetadata()
|
||||
{
|
||||
var runtimeMetadata = _implProcessor.GetRuntimeMetadata();
|
||||
|
||||
return new ServerMessageRuntimeMetadata(
|
||||
(ushort)(runtimeMetadata.InDataSize + runtimeMetadata.InObjectsCount * sizeof(int)),
|
||||
(ushort)(runtimeMetadata.OutDataSize + runtimeMetadata.OutObjectsCount * sizeof(int)),
|
||||
(byte)(runtimeMetadata.InHeadersSize + Unsafe.SizeOf<CmifDomainInHeader>()),
|
||||
(byte)(runtimeMetadata.OutHeadersSize + Unsafe.SizeOf<CmifDomainOutHeader>()),
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
public override Result PrepareForProcess(ref ServiceDispatchContext context, ServerMessageRuntimeMetadata runtimeMetadata)
|
||||
{
|
||||
if (_implMetadata.InObjectsCount != InObjectsCount)
|
||||
{
|
||||
return SfResult.InvalidInObjectsCount;
|
||||
}
|
||||
|
||||
Result result = _domain.ReserveIds(new Span<int>(_reservedObjectIds).Slice(0, OutObjectsCount));
|
||||
|
||||
if (result.IsFailure)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return _implProcessor.PrepareForProcess(ref context, runtimeMetadata);
|
||||
}
|
||||
|
||||
public override Result GetInObjects(Span<ServiceObjectHolder> inObjects)
|
||||
{
|
||||
for (int i = 0; i < InObjectsCount; i++)
|
||||
{
|
||||
inObjects[i] = _domain.GetObject(_inObjectIds[i]);
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override HipcMessageData PrepareForReply(scoped ref ServiceDispatchContext context, out Span<byte> outRawData, ServerMessageRuntimeMetadata runtimeMetadata)
|
||||
{
|
||||
var response = _implProcessor.PrepareForReply(ref context, out outRawData, runtimeMetadata);
|
||||
|
||||
int outHeaderSize = Unsafe.SizeOf<CmifDomainOutHeader>();
|
||||
int implOutDataTotalSize = ImplOutDataTotalSize;
|
||||
|
||||
DebugUtil.Assert(outHeaderSize + implOutDataTotalSize + OutObjectsCount * sizeof(int) <= outRawData.Length);
|
||||
|
||||
outRawData = outRawData.Slice(outHeaderSize);
|
||||
_outObjectIdsOffset = (response.DataWords.Length * sizeof(uint) - outRawData.Length) + implOutDataTotalSize;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override void PrepareForErrorReply(scoped ref ServiceDispatchContext context, out Span<byte> outRawData, ServerMessageRuntimeMetadata runtimeMetadata)
|
||||
{
|
||||
_implProcessor.PrepareForErrorReply(ref context, out outRawData, runtimeMetadata);
|
||||
|
||||
int outHeaderSize = Unsafe.SizeOf<CmifDomainOutHeader>();
|
||||
int implOutDataTotalSize = ImplOutDataTotalSize;
|
||||
|
||||
DebugUtil.Assert(outHeaderSize + implOutDataTotalSize <= outRawData.Length);
|
||||
|
||||
outRawData = outRawData.Slice(outHeaderSize);
|
||||
|
||||
_domain.UnreserveIds(new Span<int>(_reservedObjectIds).Slice(0, OutObjectsCount));
|
||||
}
|
||||
|
||||
public override void SetOutObjects(scoped ref ServiceDispatchContext context, HipcMessageData response, Span<ServiceObjectHolder> outObjects)
|
||||
{
|
||||
int outObjectsCount = OutObjectsCount;
|
||||
Span<int> objectIds = _reservedObjectIds;
|
||||
|
||||
for (int i = 0; i < outObjectsCount; i++)
|
||||
{
|
||||
if (outObjects[i] == null)
|
||||
{
|
||||
_domain.UnreserveIds(objectIds.Slice(i, 1));
|
||||
objectIds[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
_domain.RegisterObject(objectIds[i], outObjects[i]);
|
||||
}
|
||||
|
||||
Span<int> outObjectIds = MemoryMarshal.Cast<byte, int>(MemoryMarshal.Cast<uint, byte>(response.DataWords).Slice(_outObjectIdsOffset));
|
||||
|
||||
for (int i = 0; i < outObjectsCount; i++)
|
||||
{
|
||||
outObjectIds[i] = objectIds[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue