1
0
forked from MeloNX/MeloNX

Relax lock usage in attempt to fix a deadlock

This commit is contained in:
Gabriel A 2024-01-11 19:07:01 -03:00 committed by riperiperi
parent 092af4585c
commit 87b314a7ca
2 changed files with 30 additions and 59 deletions

View File

@ -47,14 +47,11 @@ namespace Ryujinx.Cpu.Jit
} }
public void Dispose() public void Dispose()
{
lock (_owner.Lock)
{ {
_allocation.Block.RemoveMapping(_allocation.Offset, _allocation.Size); _allocation.Block.RemoveMapping(_allocation.Offset, _allocation.Size);
_owner.Free(_allocation.Block, _allocation.Offset, _allocation.Size); _owner.Free(_allocation.Block, _allocation.Offset, _allocation.Size);
} }
} }
}
class AddressSpacePartitionAllocator : PrivateMemoryAllocatorImpl<AddressSpacePartitionAllocator.Block> class AddressSpacePartitionAllocator : PrivateMemoryAllocatorImpl<AddressSpacePartitionAllocator.Block>
{ {
@ -101,51 +98,34 @@ namespace Ryujinx.Cpu.Jit
} }
private readonly IntrusiveRedBlackTree<Mapping> _mappingTree; private readonly IntrusiveRedBlackTree<Mapping> _mappingTree;
private readonly ReaderWriterLockSlim _treeLock; private readonly object _lock;
public Block(MemoryTracking tracking, MemoryBlock memory, ulong size) : base(memory, size) public Block(MemoryTracking tracking, MemoryBlock memory, ulong size, object locker) : base(memory, size)
{ {
_tracking = tracking; _tracking = tracking;
_memoryEh = new(memory, null, tracking, VirtualMemoryEvent); _memoryEh = new(memory, null, tracking, VirtualMemoryEvent);
_mappingTree = new(); _mappingTree = new();
_treeLock = new(); _lock = locker;
} }
public void AddMapping(ulong offset, ulong size, ulong va, ulong endVa, int bridgeSize) public void AddMapping(ulong offset, ulong size, ulong va, ulong endVa, int bridgeSize)
{
_treeLock.EnterWriteLock();
try
{ {
_mappingTree.Add(new(offset, size, va, endVa, bridgeSize)); _mappingTree.Add(new(offset, size, va, endVa, bridgeSize));
} }
finally
{
_treeLock.ExitWriteLock();
}
}
public void RemoveMapping(ulong offset, ulong size) public void RemoveMapping(ulong offset, ulong size)
{
_treeLock.EnterWriteLock();
try
{ {
_mappingTree.Remove(_mappingTree.GetNode(new Mapping(offset, size, 0, 0, 0))); _mappingTree.Remove(_mappingTree.GetNode(new Mapping(offset, size, 0, 0, 0)));
} }
finally
{
_treeLock.ExitWriteLock();
}
}
private bool VirtualMemoryEvent(ulong address, ulong size, bool write) private bool VirtualMemoryEvent(ulong address, ulong size, bool write)
{ {
_treeLock.EnterReadLock(); Mapping map;
try lock (_lock)
{ {
Mapping map = _mappingTree.GetNode(new Mapping(address, size, 0, 0, 0)); map = _mappingTree.GetNode(new Mapping(address, size, 0, 0, 0));
}
if (map == null) if (map == null)
{ {
@ -161,11 +141,6 @@ namespace Ryujinx.Cpu.Jit
return _tracking.VirtualMemoryEvent(map.Va + address, size, write); return _tracking.VirtualMemoryEvent(map.Va + address, size, write);
} }
finally
{
_treeLock.ExitReadLock();
}
}
public override void Destroy() public override void Destroy()
{ {
@ -176,29 +151,25 @@ namespace Ryujinx.Cpu.Jit
} }
private readonly MemoryTracking _tracking; private readonly MemoryTracking _tracking;
private readonly object _lock;
public object Lock { get; } public AddressSpacePartitionAllocator(MemoryTracking tracking, object locker) : base(DefaultBlockAlignment, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible)
public AddressSpacePartitionAllocator(MemoryTracking tracking) : base(DefaultBlockAlignment, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible)
{ {
_tracking = tracking; _tracking = tracking;
Lock = new(); _lock = locker;
} }
public AddressSpacePartitionAllocation Allocate(ulong va, ulong size, int bridgeSize) public AddressSpacePartitionAllocation Allocate(ulong va, ulong size, int bridgeSize)
{
lock (Lock)
{ {
AddressSpacePartitionAllocation allocation = new(this, Allocate(size + (ulong)bridgeSize, MemoryBlock.GetPageSize(), CreateBlock)); AddressSpacePartitionAllocation allocation = new(this, Allocate(size + (ulong)bridgeSize, MemoryBlock.GetPageSize(), CreateBlock));
allocation.RegisterMapping(va, va + size, bridgeSize); allocation.RegisterMapping(va, va + size, bridgeSize);
return allocation; return allocation;
} }
}
private Block CreateBlock(MemoryBlock memory, ulong size) private Block CreateBlock(MemoryBlock memory, ulong size)
{ {
return new Block(_tracking, memory, size); return new Block(_tracking, memory, size, _lock);
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace Ryujinx.Cpu.Jit
{ {
_backingMemory = backingMemory; _backingMemory = backingMemory;
_partitions = new(); _partitions = new();
_asAllocator = new(tracking); _asAllocator = new(tracking, _partitions);
_updatePtCallback = updatePtCallback; _updatePtCallback = updatePtCallback;
} }