KTransferMemory.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using Ryujinx.HLE.HOS.Kernel.Common;
  2. using Ryujinx.HLE.HOS.Kernel.Process;
  3. using System;
  4. namespace Ryujinx.HLE.HOS.Kernel.Memory
  5. {
  6. class KTransferMemory : KAutoObject
  7. {
  8. private KProcess _creator;
  9. // TODO: Remove when we no longer need to read it from the owner directly.
  10. public KProcess Creator => _creator;
  11. private readonly KPageList _pageList;
  12. public ulong Address { get; private set; }
  13. public ulong Size => _pageList.GetPagesCount() * KMemoryManager.PageSize;
  14. public KMemoryPermission Permission { get; private set; }
  15. private bool _hasBeenInitialized;
  16. private bool _isMapped;
  17. public KTransferMemory(KernelContext context) : base(context)
  18. {
  19. _pageList = new KPageList();
  20. }
  21. public KernelResult Initialize(ulong address, ulong size, KMemoryPermission permission)
  22. {
  23. KProcess creator = KernelStatic.GetCurrentProcess();
  24. _creator = creator;
  25. KernelResult result = creator.MemoryManager.BorrowTransferMemory(_pageList, address, size, permission);
  26. if (result != KernelResult.Success)
  27. {
  28. return result;
  29. }
  30. creator.IncrementReferenceCount();
  31. Permission = permission;
  32. Address = address;
  33. _hasBeenInitialized = true;
  34. _isMapped = false;
  35. return result;
  36. }
  37. protected override void Destroy()
  38. {
  39. if (_hasBeenInitialized)
  40. {
  41. if (!_isMapped && _creator.MemoryManager.UnborrowTransferMemory(Address, Size, _pageList) != KernelResult.Success)
  42. {
  43. throw new InvalidOperationException("Unexpected failure restoring transfer memory attributes.");
  44. }
  45. _creator.ResourceLimit?.Release(LimitableResource.TransferMemory, 1);
  46. _creator.DecrementReferenceCount();
  47. }
  48. }
  49. }
  50. }