diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-07-19 15:24:18 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-19 15:24:18 -0300 |
| commit | e7f2a5ecb709ff3ee82bb39ab32a16b5db0c101d (patch) | |
| tree | f1931e1db2d0e6772d014856ab09ce1e78a8787c /Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs | |
| parent | 3af2ce74ecf76cc8d6fdb9ff19101bfee47af7dd (diff) | |
Fix session service disposal and improve transfer memory implementation (#1397)
* Fix session service disposal and improve transfer memory implementation
* Remove useless assignment
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs index 6da0c405..d3e6208e 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KTransferMemory.cs @@ -1,16 +1,63 @@ using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Kernel.Process; +using System; namespace Ryujinx.HLE.HOS.Kernel.Memory { class KTransferMemory : KAutoObject { + private KProcess _creator; + + private readonly KPageList _pageList; + public ulong Address { get; private set; } - public ulong Size { get; private set; } + public ulong Size => _pageList.GetPagesCount() * KMemoryManager.PageSize; + + public MemoryPermission Permission { get; private set; } - public KTransferMemory(KernelContext context, ulong address, ulong size) : base(context) + private bool _hasBeenInitialized; + private bool _isMapped; + + public KTransferMemory(KernelContext context) : base(context) { + _pageList = new KPageList(); + } + + public KernelResult Initialize(ulong address, ulong size, MemoryPermission permission) + { + KProcess creator = KernelContext.Scheduler.GetCurrentProcess(); + + _creator = creator; + + KernelResult result = creator.MemoryManager.BorrowTransferMemory(_pageList, address, size, permission); + + if (result != KernelResult.Success) + { + return result; + } + + creator.IncrementReferenceCount(); + + Permission = permission; Address = address; - Size = size; + _hasBeenInitialized = true; + _isMapped = false; + + return result; + } + + protected override void Destroy() + { + if (_hasBeenInitialized) + { + if (!_isMapped && _creator.MemoryManager.UnborrowTransferMemory(Address, Size, _pageList) != KernelResult.Success) + { + throw new InvalidOperationException("Unexpected failure restoring transfer memory attributes."); + } + + _creator.ResourceLimit?.Release(LimitableResource.TransferMemory, 1); + _creator.DecrementReferenceCount(); + } } } }
\ No newline at end of file |
