65 lines
1.9 KiB
C#
65 lines
1.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|