diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs index a8455bdb90..a52b36a225 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs @@ -3,7 +3,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Memory; using System; -using System.Collections.Concurrent; 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 static ConcurrentDictionary _maps = new ConcurrentDictionary(); + private static NvMapIdDictionary _maps = new NvMapIdDictionary(); 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 arguments) @@ -232,19 +228,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap private int CreateHandleFromMap(NvMapHandle map) { - IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary()); - - return dict.Add(map); + return _maps.Add(map); } private static bool DeleteMapWithHandle(ulong pid, int handle) { - if (_maps.TryGetValue(pid, out IdDictionary dict)) - { - return dict.Delete(handle) != null; - } - - return false; + return _maps.Delete(handle) != null; } 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) { - if (_maps.TryGetValue(pid, out IdDictionary dict)) - { - return dict.GetData(handle); - } - - return null; + return _maps.Get(handle); } } } diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapIdDictionary.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapIdDictionary.cs new file mode 100644 index 0000000000..c4733e9487 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapIdDictionary.cs @@ -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 _nvmapHandles; + private int _id; + + public ICollection Values => _nvmapHandles.Values; + + public NvMapIdDictionary() + { + _nvmapHandles = new ConcurrentDictionary(); + } + + 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 Clear() + { + ICollection values = _nvmapHandles.Values; + + _nvmapHandles.Clear(); + + return values; + } + } +} \ No newline at end of file