See merge request ryubing/ryujinx!132
This commit is contained in:
LotP
2025-08-30 20:30:17 -05:00
parent 6e47d8548c
commit 01a9b636af
7 changed files with 161 additions and 84 deletions

View File

@@ -87,6 +87,43 @@ namespace Ryujinx.Memory.Range
return false;
}
/// <summary>
/// Updates an item's end address on the list. Address must be the same.
/// </summary>
/// <param name="item">The RangeItem to be updated</param>
/// <returns>True if the item was located and updated, false otherwise</returns>
protected override bool Update(RangeItem<T> item)
{
int index = BinarySearch(item.Address);
RangeItem<T> rangeItem = new(item.Value) { Previous = item.Previous, Next = item.Next };
if (index > 0)
{
Items[index - 1].Next = rangeItem;
}
if (index < Count - 1)
{
Items[index + 1].Previous = rangeItem;
}
foreach (ulong addr in item.QuickAccessAddresses)
{
_quickAccess.Remove(addr);
_fastQuickAccess.Remove(addr);
}
Items[index] = rangeItem;
if (item.Address != rangeItem.Address)
_quickAccess.Remove(item.Address);
_quickAccess[rangeItem.Address] = rangeItem;
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Insert(int index, RangeItem<T> item)
{
@@ -193,10 +230,9 @@ namespace Ryujinx.Memory.Range
return;
}
int startIndex = BinarySearch(startItem.Address);
int endIndex = BinarySearch(endItem.Address);
(int startIndex, int endIndex) = BinarySearchEdges(startItem.Address, endItem.EndAddress);
for (int i = startIndex; i <= endIndex; i++)
for (int i = startIndex; i < endIndex; i++)
{
_quickAccess.Remove(Items[i].Address);
foreach (ulong addr in Items[i].QuickAccessAddresses)
@@ -206,23 +242,23 @@ namespace Ryujinx.Memory.Range
}
}
if (endIndex < Count - 1)
if (endIndex < Count)
{
Items[endIndex + 1].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
Items[endIndex].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
}
if (startIndex > 0)
{
Items[startIndex - 1].Next = endIndex < Count - 1 ? Items[endIndex + 1] : null;
Items[startIndex - 1].Next = endIndex < Count ? Items[endIndex] : null;
}
if (endIndex < Count - 1)
if (endIndex < Count)
{
Array.Copy(Items, endIndex + 1, Items, startIndex, Count - endIndex - 1);
Array.Copy(Items, endIndex, Items, startIndex, Count - endIndex);
}
Count -= endIndex - startIndex + 1;
Count -= endIndex - startIndex;
}
/// <summary>

View File

@@ -81,12 +81,73 @@ namespace Ryujinx.Memory.Range
{
if (Items[index].Value.Equals(item))
{
RangeItem<T> rangeItem = new(item) { Previous = Items[index].Previous, Next = Items[index].Next };
if (index > 0)
{
Items[index - 1].Next = rangeItem;
}
if (index < Count - 1)
{
Items[index + 1].Previous = rangeItem;
}
foreach (ulong address in Items[index].QuickAccessAddresses)
{
_quickAccess.Remove(address);
}
Items[index] = new RangeItem<T>(item);
Items[index] = rangeItem;
return true;
}
if (Items[index].Address > item.Address)
{
break;
}
index++;
}
}
return false;
}
/// <summary>
/// Updates an item's end address on the list. Address must be the same.
/// </summary>
/// <param name="item">The RangeItem to be updated</param>
/// <returns>True if the item was located and updated, false otherwise</returns>
protected override bool Update(RangeItem<T> item)
{
int index = BinarySearch(item.Address);
if (index >= 0)
{
while (index < Count)
{
if (Items[index].Equals(item))
{
RangeItem<T> rangeItem = new(item.Value) { Previous = item.Previous, Next = item.Next };
if (index > 0)
{
Items[index - 1].Next = rangeItem;
}
if (index < Count - 1)
{
Items[index + 1].Previous = rangeItem;
}
foreach (ulong address in item.QuickAccessAddresses)
{
_quickAccess.Remove(address);
}
Items[index] = rangeItem;
return true;
}

View File

@@ -30,7 +30,7 @@ namespace Ryujinx.Memory.Range
return u1 == u2;
}
public int GetHashCode(ulong value) => (int)(value >> 5);
public int GetHashCode(ulong value) => (int)(value << 5);
public static readonly AddressEqualityComparer Comparer = new();
}
@@ -63,6 +63,13 @@ namespace Ryujinx.Memory.Range
/// <returns>True if the item was located and updated, false otherwise</returns>
protected abstract bool Update(T item);
/// <summary>
/// Updates an item's end address on the list. Address must be the same.
/// </summary>
/// <param name="item">The RangeItem to be updated</param>
/// <returns>True if the item was located and updated, false otherwise</returns>
protected abstract bool Update(RangeItem<T> item);
public abstract bool Remove(T item);
public abstract void RemoveRange(RangeItem<T> startItem, RangeItem<T> endItem);

View File

@@ -182,11 +182,15 @@ namespace Ryujinx.Memory.Tracking
{
if (region.Guest)
{
_guestVirtualRegions.Lock.EnterWriteLock();
_guestVirtualRegions.Remove(region);
_guestVirtualRegions.Lock.ExitWriteLock();
}
else
{
_virtualRegions.Lock.EnterWriteLock();
_virtualRegions.Remove(region);
_virtualRegions.Lock.ExitWriteLock();
}
}