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