ConcurrentBitmap: Use Interlocked Or/And (#3937)

This commit is contained in:
merry 2022-11-29 13:47:57 +00:00 committed by GitHub
parent d41c95dcff
commit a5c2aead67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -41,7 +41,7 @@ namespace Ryujinx.Memory.Tracking
{ {
for (int i = 0; i < Masks.Length; i++) for (int i = 0; i < Masks.Length; i++)
{ {
if (Volatile.Read(ref Masks[i]) != 0) if (Interlocked.Read(ref Masks[i]) != 0)
{ {
return true; return true;
} }
@ -62,7 +62,7 @@ namespace Ryujinx.Memory.Tracking
long wordMask = 1L << wordBit; long wordMask = 1L << wordBit;
return (Volatile.Read(ref Masks[wordIndex]) & wordMask) != 0; return (Interlocked.Read(ref Masks[wordIndex]) & wordMask) != 0;
} }
/// <summary> /// <summary>
@ -86,7 +86,7 @@ namespace Ryujinx.Memory.Tracking
int endBit = end & IntMask; int endBit = end & IntMask;
long endMask = (long)(ulong.MaxValue >> (IntMask - endBit)); long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
long startValue = Volatile.Read(ref Masks[startIndex]); long startValue = Interlocked.Read(ref Masks[startIndex]);
if (startIndex == endIndex) if (startIndex == endIndex)
{ {
@ -100,13 +100,13 @@ namespace Ryujinx.Memory.Tracking
for (int i = startIndex + 1; i < endIndex; i++) for (int i = startIndex + 1; i < endIndex; i++)
{ {
if (Volatile.Read(ref Masks[i]) != 0) if (Interlocked.Read(ref Masks[i]) != 0)
{ {
return true; return true;
} }
} }
long endValue = Volatile.Read(ref Masks[endIndex]); long endValue = Interlocked.Read(ref Masks[endIndex]);
if ((endValue & endMask) != 0) if ((endValue & endMask) != 0)
{ {
@ -128,23 +128,14 @@ namespace Ryujinx.Memory.Tracking
long wordMask = 1L << wordBit; long wordMask = 1L << wordBit;
long existing; if (value)
long newValue;
do
{ {
existing = Volatile.Read(ref Masks[wordIndex]); Interlocked.Or(ref Masks[wordIndex], wordMask);
}
if (value) else
{ {
newValue = existing | wordMask; Interlocked.And(ref Masks[wordIndex], ~wordMask);
}
else
{
newValue = existing & ~wordMask;
}
} }
while (Interlocked.CompareExchange(ref Masks[wordIndex], newValue, existing) != existing);
} }
/// <summary> /// <summary>
@ -154,7 +145,7 @@ namespace Ryujinx.Memory.Tracking
{ {
for (int i = 0; i < Masks.Length; i++) for (int i = 0; i < Masks.Length; i++)
{ {
Volatile.Write(ref Masks[i], 0); Interlocked.Exchange(ref Masks[i], 0);
} }
} }
} }