Change NvMap ID allocation to match nvservices (#3741)

* Change NvMap ID allocation to match nvservices

* Move NvMapIdDictionary to Types
This commit is contained in:
gdkchan 2022-10-05 17:49:18 -03:00 committed by GitHub
parent 60e16c15b6
commit 599d485bff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 20 deletions

View file

@ -3,7 +3,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.Collections.Concurrent;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{ {
@ -11,13 +10,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{ {
private const int FlagNotFreedYet = 1; private const int FlagNotFreedYet = 1;
private static ConcurrentDictionary<ulong, IdDictionary> _maps = new ConcurrentDictionary<ulong, IdDictionary>(); private static NvMapIdDictionary _maps = new NvMapIdDictionary();
public NvMapDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner) public NvMapDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner)
{ {
IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary());
dict.Add(0, new NvMapHandle());
} }
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments) public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
@ -232,19 +228,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
private int CreateHandleFromMap(NvMapHandle map) private int CreateHandleFromMap(NvMapHandle map)
{ {
IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary()); return _maps.Add(map);
return dict.Add(map);
} }
private static bool DeleteMapWithHandle(ulong pid, int handle) private static bool DeleteMapWithHandle(ulong pid, int handle)
{ {
if (_maps.TryGetValue(pid, out IdDictionary dict)) return _maps.Delete(handle) != null;
{
return dict.Delete(handle) != null;
}
return false;
} }
public static void IncrementMapRefCount(ulong pid, int handle) public static void IncrementMapRefCount(ulong pid, int handle)
@ -277,12 +266,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
public static NvMapHandle GetMapFromHandle(ulong pid, int handle) public static NvMapHandle GetMapFromHandle(ulong pid, int handle)
{ {
if (_maps.TryGetValue(pid, out IdDictionary dict)) return _maps.Get(handle);
{
return dict.GetData<NvMapHandle>(handle);
}
return null;
} }
} }
} }

View file

@ -0,0 +1,61 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{
class NvMapIdDictionary
{
private readonly ConcurrentDictionary<int, NvMapHandle> _nvmapHandles;
private int _id;
public ICollection<NvMapHandle> Values => _nvmapHandles.Values;
public NvMapIdDictionary()
{
_nvmapHandles = new ConcurrentDictionary<int, NvMapHandle>();
}
public int Add(NvMapHandle handle)
{
int id = Interlocked.Add(ref _id, 4);
if (id != 0 && _nvmapHandles.TryAdd(id, handle))
{
return id;
}
throw new InvalidOperationException("NvMap ID overflow.");
}
public NvMapHandle Get(int id)
{
if (_nvmapHandles.TryGetValue(id, out NvMapHandle handle))
{
return handle;
}
return null;
}
public NvMapHandle Delete(int id)
{
if (_nvmapHandles.TryRemove(id, out NvMapHandle handle))
{
return handle;
}
return null;
}
public ICollection<NvMapHandle> Clear()
{
ICollection<NvMapHandle> values = _nvmapHandles.Values;
_nvmapHandles.Clear();
return values;
}
}
}