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;