KMemoryManager.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using Ryujinx.HLE.HOS.Kernel.Common;
  2. using System;
  3. namespace Ryujinx.HLE.HOS.Kernel.Memory
  4. {
  5. class KMemoryManager
  6. {
  7. public KMemoryRegionManager[] MemoryRegions { get; }
  8. public KMemoryManager(MemorySize size, MemoryArrange arrange)
  9. {
  10. MemoryRegions = KernelInit.GetMemoryRegions(size, arrange);
  11. }
  12. private KMemoryRegionManager GetMemoryRegion(ulong address)
  13. {
  14. for (int i = 0; i < MemoryRegions.Length; i++)
  15. {
  16. var region = MemoryRegions[i];
  17. if (address >= region.Address && address < region.EndAddr)
  18. {
  19. return region;
  20. }
  21. }
  22. return null;
  23. }
  24. public void IncrementPagesReferenceCount(ulong address, ulong pagesCount)
  25. {
  26. IncrementOrDecrementPagesReferenceCount(address, pagesCount, true);
  27. }
  28. public void DecrementPagesReferenceCount(ulong address, ulong pagesCount)
  29. {
  30. IncrementOrDecrementPagesReferenceCount(address, pagesCount, false);
  31. }
  32. private void IncrementOrDecrementPagesReferenceCount(ulong address, ulong pagesCount, bool increment)
  33. {
  34. while (pagesCount != 0)
  35. {
  36. var region = GetMemoryRegion(address);
  37. ulong countToProcess = Math.Min(pagesCount, region.GetPageOffsetFromEnd(address));
  38. lock (region)
  39. {
  40. if (increment)
  41. {
  42. region.IncrementPagesReferenceCount(address, countToProcess);
  43. }
  44. else
  45. {
  46. region.DecrementPagesReferenceCount(address, countToProcess);
  47. }
  48. }
  49. pagesCount -= countToProcess;
  50. address += countToProcess * KPageTableBase.PageSize;
  51. }
  52. }
  53. }
  54. }