diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-09-25 20:50:06 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-26 01:50:06 +0200 |
| commit | 4a835bb2b9130b91d35968b2f7800084cf286de4 (patch) | |
| tree | 61d927b3b09ff00520e428331e78d97758926034 /src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs | |
| parent | ddc9ae2a8380668273c21a75b11b833be76eebed (diff) | |
Make Vulkan memory allocator actually thread safe (#5575)
* Make Vulkan memory allocator actually thread safe
* Make free thread safe too
* PR feedback
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs')
| -rw-r--r-- | src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs b/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs index ab700627..aa0b410c 100644 --- a/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs +++ b/src/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs @@ -1,6 +1,7 @@ using Silk.NET.Vulkan; using System; using System.Collections.Generic; +using System.Threading; namespace Ryujinx.Graphics.Vulkan { @@ -13,6 +14,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly Device _device; private readonly List<MemoryAllocatorBlockList> _blockLists; private readonly int _blockAlignment; + private readonly ReaderWriterLockSlim _lock; public MemoryAllocator(Vk api, VulkanPhysicalDevice physicalDevice, Device device) { @@ -21,6 +23,7 @@ namespace Ryujinx.Graphics.Vulkan _device = device; _blockLists = new List<MemoryAllocatorBlockList>(); _blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / _physicalDevice.PhysicalDeviceProperties.Limits.MaxMemoryAllocationCount); + _lock = new(LockRecursionPolicy.NoRecursion); } public MemoryAllocation AllocateDeviceMemory( @@ -40,21 +43,37 @@ namespace Ryujinx.Graphics.Vulkan private MemoryAllocation Allocate(int memoryTypeIndex, ulong size, ulong alignment, bool map, bool isBuffer) { - for (int i = 0; i < _blockLists.Count; i++) + _lock.EnterReadLock(); + + try { - var bl = _blockLists[i]; - if (bl.MemoryTypeIndex == memoryTypeIndex && bl.ForBuffer == isBuffer) + for (int i = 0; i < _blockLists.Count; i++) { - lock (bl) + var bl = _blockLists[i]; + if (bl.MemoryTypeIndex == memoryTypeIndex && bl.ForBuffer == isBuffer) { return bl.Allocate(size, alignment, map); } } } + finally + { + _lock.ExitReadLock(); + } + + _lock.EnterWriteLock(); - var newBl = new MemoryAllocatorBlockList(_api, _device, memoryTypeIndex, _blockAlignment, isBuffer); - _blockLists.Add(newBl); - return newBl.Allocate(size, alignment, map); + try + { + var newBl = new MemoryAllocatorBlockList(_api, _device, memoryTypeIndex, _blockAlignment, isBuffer); + _blockLists.Add(newBl); + + return newBl.Allocate(size, alignment, map); + } + finally + { + _lock.ExitWriteLock(); + } } internal int FindSuitableMemoryTypeIndex( |
