blob: 6d0a165815d2dac56b84e7ccad05f9ffc00fb34e (
plain) (
tree)
|
|
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;
}
}
}
}
|