feat: free up pages from terminated applets
This commit is contained in:
parent
a9854ec30d
commit
f2cf73f145
@ -1,4 +1,5 @@
|
||||
using Ryujinx.Horizon.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
@ -12,6 +13,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
public ulong EndAddr => Address + Size;
|
||||
|
||||
private readonly ushort[] _pageReferenceCounts;
|
||||
public Dictionary<ulong, List<KPageList>> Regions { get; } = new Dictionary<ulong, List<KPageList>>();
|
||||
|
||||
public KMemoryRegionManager(ulong address, ulong size, ulong endAddr)
|
||||
{
|
||||
@ -25,7 +27,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
_pageHeap.UpdateUsedSize();
|
||||
}
|
||||
|
||||
public Result AllocatePages(out KPageList pageList, ulong pagesCount)
|
||||
public Result AllocatePages(out KPageList pageList, ulong pagesCount, ulong pid)
|
||||
{
|
||||
if (pagesCount == 0)
|
||||
{
|
||||
@ -36,7 +38,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
|
||||
lock (_pageHeap)
|
||||
{
|
||||
Result result = AllocatePagesImpl(out pageList, pagesCount, false);
|
||||
Result result = AllocatePagesImpl(out pageList, pagesCount, false, pid);
|
||||
|
||||
if (result == Result.Success)
|
||||
{
|
||||
@ -71,7 +73,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
}
|
||||
|
||||
private Result AllocatePagesImpl(out KPageList pageList, ulong pagesCount, bool random)
|
||||
private Result AllocatePagesImpl(out KPageList pageList, ulong pagesCount, bool random, ulong pid)
|
||||
{
|
||||
pageList = new KPageList();
|
||||
|
||||
@ -109,6 +111,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
}
|
||||
|
||||
if (Regions.ContainsKey(pid))
|
||||
{
|
||||
Regions[pid].Add(pageList);
|
||||
}
|
||||
else
|
||||
{
|
||||
Regions.Add(pid, new List<KPageList>() { pageList });
|
||||
}
|
||||
|
||||
if (pagesCount != 0)
|
||||
{
|
||||
FreePages(pageList);
|
||||
@ -116,9 +127,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
return KernelResult.OutOfMemory;
|
||||
}
|
||||
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public void ClearFromPid(ulong pid)
|
||||
{
|
||||
if (Regions.TryGetValue(pid, out List<KPageList> pageLists))
|
||||
{
|
||||
foreach (KPageList pageList in pageLists)
|
||||
{
|
||||
FreePages(pageList);
|
||||
}
|
||||
Regions.Remove(pid);
|
||||
}
|
||||
}
|
||||
|
||||
private ulong AllocatePagesContiguousImpl(ulong pagesCount, ulong alignPages, bool random)
|
||||
{
|
||||
int heapIndex = KPageHeap.GetAlignedBlockIndex(pagesCount, alignPages);
|
||||
|
@ -523,7 +523,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
ulong regionPagesCount,
|
||||
MemoryState state,
|
||||
KMemoryPermission permission,
|
||||
out ulong address)
|
||||
out ulong address, ulong pid)
|
||||
{
|
||||
address = 0;
|
||||
|
||||
@ -561,7 +561,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
else
|
||||
{
|
||||
result = AllocateAndMapPages(address, pagesCount, permission);
|
||||
result = AllocateAndMapPages(address, pagesCount, permission, pid);
|
||||
}
|
||||
|
||||
if (result != Result.Success)
|
||||
@ -575,7 +575,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result MapPages(ulong address, ulong pagesCount, MemoryState state, KMemoryPermission permission)
|
||||
public Result MapPages(ulong address, ulong pagesCount, MemoryState state, KMemoryPermission permission, ulong pid)
|
||||
{
|
||||
ulong size = pagesCount * PageSize;
|
||||
|
||||
@ -596,7 +596,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
return KernelResult.OutOfResource;
|
||||
}
|
||||
|
||||
Result result = AllocateAndMapPages(address, pagesCount, permission);
|
||||
Result result = AllocateAndMapPages(address, pagesCount, permission,pid);
|
||||
|
||||
if (result == Result.Success)
|
||||
{
|
||||
@ -607,11 +607,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
}
|
||||
|
||||
private Result AllocateAndMapPages(ulong address, ulong pagesCount, KMemoryPermission permission)
|
||||
private Result AllocateAndMapPages(ulong address, ulong pagesCount, KMemoryPermission permission, ulong pid)
|
||||
{
|
||||
KMemoryRegionManager region = GetMemoryRegionManager();
|
||||
|
||||
Result result = region.AllocatePages(out KPageList pageList, pagesCount);
|
||||
Result result = region.AllocatePages(out KPageList pageList, pagesCount,pid);
|
||||
|
||||
if (result != Result.Success)
|
||||
{
|
||||
@ -738,7 +738,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
}
|
||||
|
||||
public Result SetHeapSize(ulong size, out ulong address)
|
||||
public Result SetHeapSize(ulong size, out ulong address, ulong pid)
|
||||
{
|
||||
address = 0;
|
||||
|
||||
@ -768,7 +768,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
|
||||
KMemoryRegionManager region = GetMemoryRegionManager();
|
||||
|
||||
Result result = region.AllocatePages(out KPageList pageList, pagesCount);
|
||||
Result result = region.AllocatePages(out KPageList pageList, pagesCount, pid);
|
||||
|
||||
using OnScopeExit _ = new(() => pageList.DecrementPagesReferenceCount(Context.MemoryManager));
|
||||
|
||||
@ -1305,7 +1305,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
}
|
||||
}
|
||||
|
||||
public Result MapPhysicalMemory(ulong address, ulong size)
|
||||
public Result MapPhysicalMemory(ulong address, ulong size, ulong pid)
|
||||
{
|
||||
ulong endAddr = address + size;
|
||||
|
||||
@ -1340,7 +1340,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
|
||||
KMemoryRegionManager region = GetMemoryRegionManager();
|
||||
|
||||
Result result = region.AllocatePages(out KPageList pageList, remainingPages);
|
||||
Result result = region.AllocatePages(out KPageList pageList, remainingPages, pid);
|
||||
|
||||
using OnScopeExit _ = new(() => pageList.DecrementPagesReferenceCount(Context.MemoryManager));
|
||||
|
||||
@ -2884,7 +2884,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||
return pa - DramMemoryMap.DramBase;
|
||||
}
|
||||
|
||||
protected KMemoryRegionManager GetMemoryRegionManager()
|
||||
public KMemoryRegionManager GetMemoryRegionManager()
|
||||
{
|
||||
return Context.MemoryManager.MemoryRegions[(int)_memRegion];
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
codeAddress,
|
||||
codePagesCount,
|
||||
MemoryState.CodeStatic,
|
||||
KMemoryPermission.None);
|
||||
KMemoryPermission.None, Pid);
|
||||
|
||||
if (result != Result.Success)
|
||||
{
|
||||
@ -437,7 +437,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
regionPagesCount,
|
||||
MemoryState.ThreadLocal,
|
||||
KMemoryPermission.ReadAndWrite,
|
||||
out ulong tlsPageVa);
|
||||
out ulong tlsPageVa,Pid);
|
||||
|
||||
if (result != Result.Success)
|
||||
{
|
||||
@ -607,7 +607,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
regionPagesCount,
|
||||
MemoryState.Stack,
|
||||
KMemoryPermission.ReadAndWrite,
|
||||
out ulong stackBottom);
|
||||
out ulong stackBottom,Pid);
|
||||
|
||||
if (result != Result.Success)
|
||||
{
|
||||
@ -872,6 +872,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
public Result Terminate()
|
||||
{
|
||||
if (Switch.Shared.System.WindowSystem.GetByAruId(Pid) != null)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Service, $"Attempting to terminate a running application window system for PID {Pid}");
|
||||
MemoryManager.GetMemoryRegionManager().ClearFromPid(Pid);
|
||||
}
|
||||
Result result;
|
||||
|
||||
bool shallTerminate = false;
|
||||
|
@ -897,7 +897,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||
|
||||
KProcess process = KernelStatic.GetCurrentProcess();
|
||||
|
||||
return process.MemoryManager.SetHeapSize(size, out address);
|
||||
return process.MemoryManager.SetHeapSize(size, out address, process.Pid);
|
||||
}
|
||||
|
||||
[Svc(2)]
|
||||
@ -1364,7 +1364,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||
|
||||
KProcess process = KernelStatic.GetCurrentProcess();
|
||||
|
||||
return process.MemoryManager.MapPhysicalMemory(address, size);
|
||||
return process.MemoryManager.MapPhysicalMemory(address, size, process.Pid);
|
||||
}
|
||||
|
||||
[Svc(0x2d)]
|
||||
|
@ -169,7 +169,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
||||
MemoryRegion memoryRegion = kip.UsesSecureMemory ? MemoryRegion.Service : MemoryRegion.Application;
|
||||
KMemoryRegionManager region = context.MemoryManager.MemoryRegions[(int)memoryRegion];
|
||||
|
||||
Result result = region.AllocatePages(out KPageList pageList, (ulong)codePagesCount);
|
||||
Result result = region.AllocatePages(out KPageList pageList, (ulong)codePagesCount, 0);
|
||||
if (result != Result.Success)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
|
||||
|
Loading…
x
Reference in New Issue
Block a user