KPageList.cs
1 using Ryujinx.Horizon.Common; 2 using System.Collections; 3 using System.Collections.Generic; 4 5 namespace Ryujinx.HLE.HOS.Kernel.Memory 6 { 7 class KPageList : IEnumerable<KPageNode> 8 { 9 public LinkedList<KPageNode> Nodes { get; } 10 11 public KPageList() 12 { 13 Nodes = new LinkedList<KPageNode>(); 14 } 15 16 public Result AddRange(ulong address, ulong pagesCount) 17 { 18 if (pagesCount != 0) 19 { 20 if (Nodes.Last != null) 21 { 22 KPageNode lastNode = Nodes.Last.Value; 23 24 if (lastNode.Address + lastNode.PagesCount * KPageTableBase.PageSize == address) 25 { 26 address = lastNode.Address; 27 pagesCount += lastNode.PagesCount; 28 29 Nodes.RemoveLast(); 30 } 31 } 32 33 Nodes.AddLast(new KPageNode(address, pagesCount)); 34 } 35 36 return Result.Success; 37 } 38 39 public ulong GetPagesCount() 40 { 41 ulong sum = 0; 42 43 foreach (KPageNode node in Nodes) 44 { 45 sum += node.PagesCount; 46 } 47 48 return sum; 49 } 50 51 public bool IsEqual(KPageList other) 52 { 53 LinkedListNode<KPageNode> thisNode = Nodes.First; 54 LinkedListNode<KPageNode> otherNode = other.Nodes.First; 55 56 while (thisNode != null && otherNode != null) 57 { 58 if (thisNode.Value.Address != otherNode.Value.Address || 59 thisNode.Value.PagesCount != otherNode.Value.PagesCount) 60 { 61 return false; 62 } 63 64 thisNode = thisNode.Next; 65 otherNode = otherNode.Next; 66 } 67 68 return thisNode == null && otherNode == null; 69 } 70 71 public void IncrementPagesReferenceCount(KMemoryManager manager) 72 { 73 foreach (var node in this) 74 { 75 manager.IncrementPagesReferenceCount(node.Address, node.PagesCount); 76 } 77 } 78 79 public void DecrementPagesReferenceCount(KMemoryManager manager) 80 { 81 foreach (var node in this) 82 { 83 manager.DecrementPagesReferenceCount(node.Address, node.PagesCount); 84 } 85 } 86 87 public IEnumerator<KPageNode> GetEnumerator() 88 { 89 return Nodes.GetEnumerator(); 90 } 91 92 IEnumerator IEnumerable.GetEnumerator() 93 { 94 return GetEnumerator(); 95 } 96 } 97 }