/ src / Ryujinx.HLE / HOS / Kernel / Memory / KPageList.cs
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  }