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

@ -48,11 +48,8 @@ namespace Ryujinx.Cpu.Jit
public void Dispose() public void Dispose()
{ {
lock (_owner.Lock) _allocation.Block.RemoveMapping(_allocation.Offset, _allocation.Size);
{ _owner.Free(_allocation.Block, _allocation.Offset, _allocation.Size);
_allocation.Block.RemoveMapping(_allocation.Offset, _allocation.Size);
_owner.Free(_allocation.Block, _allocation.Offset, _allocation.Size);
}
} }
} }
@ -101,70 +98,48 @@ 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(); _mappingTree.Add(new(offset, size, va, endVa, bridgeSize));
try
{
_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(); _mappingTree.Remove(_mappingTree.GetNode(new Mapping(offset, size, 0, 0, 0)));
try
{
_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)
{
return false;
}
address -= map.Address;
if (address >= (map.EndVa - map.Va))
{
address -= (ulong)(map.BridgeSize / 2);
}
return _tracking.VirtualMemoryEvent(map.Va + address, size, write);
} }
finally
if (map == null)
{ {
_treeLock.ExitReadLock(); return false;
} }
address -= map.Address;
if (address >= (map.EndVa - map.Va))
{
address -= (ulong)(map.BridgeSize / 2);
}
return _tracking.VirtualMemoryEvent(map.Va + address, size, write);
} }
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));
{ allocation.RegisterMapping(va, va + size, bridgeSize);
AddressSpacePartitionAllocation allocation = new(this, Allocate(size + (ulong)bridgeSize, MemoryBlock.GetPageSize(), CreateBlock));
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;
} }