diff options
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs')
| -rw-r--r-- | src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs new file mode 100644 index 00000000..6d0a1658 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs @@ -0,0 +1,65 @@ +using Ryujinx.HLE.HOS.Kernel.Common; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Memory +{ + class KMemoryManager + { + public KMemoryRegionManager[] MemoryRegions { get; } + + public KMemoryManager(MemorySize size, MemoryArrange arrange) + { + MemoryRegions = KernelInit.GetMemoryRegions(size, arrange); + } + + private KMemoryRegionManager GetMemoryRegion(ulong address) + { + for (int i = 0; i < MemoryRegions.Length; i++) + { + var region = MemoryRegions[i]; + + if (address >= region.Address && address < region.EndAddr) + { + return region; + } + } + + return null; + } + + public void IncrementPagesReferenceCount(ulong address, ulong pagesCount) + { + IncrementOrDecrementPagesReferenceCount(address, pagesCount, true); + } + + public void DecrementPagesReferenceCount(ulong address, ulong pagesCount) + { + IncrementOrDecrementPagesReferenceCount(address, pagesCount, false); + } + + private void IncrementOrDecrementPagesReferenceCount(ulong address, ulong pagesCount, bool increment) + { + while (pagesCount != 0) + { + var region = GetMemoryRegion(address); + + ulong countToProcess = Math.Min(pagesCount, region.GetPageOffsetFromEnd(address)); + + lock (region) + { + if (increment) + { + region.IncrementPagesReferenceCount(address, countToProcess); + } + else + { + region.DecrementPagesReferenceCount(address, countToProcess); + } + } + + pagesCount -= countToProcess; + address += countToProcess * KPageTableBase.PageSize; + } + } + } +} |
