aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-04-25 10:25:22 -0300
committerGitHub <noreply@github.com>2020-04-25 23:25:22 +1000
commitbcc5b0d21ec68732c3db37147e07800e3851892a (patch)
tree6fb846f6a31451c28bbd4dc94b007e02e4eba26a
parent74f8a9bd799989197ff8b2cc26ab11b64d55f3f7 (diff)
Fix kernel memory allocator block coalescing (#1155)
* Fix kernel memory allocator block coalescing * Fix and move clear bit logic to a separate method
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs64
1 files changed, 54 insertions, 10 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
index 3334ff43..9a773495 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs
@@ -12,20 +12,68 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public int Order;
public int NextOrder;
- public bool TryCoalesce(int index, int size)
+ public bool TryCoalesce(int index, int count)
{
- long mask = ((1L << size) - 1) << (index & 63);
+ long mask = ((1L << count) - 1) << (index & 63);
index /= 64;
- if ((mask & ~Masks[MaxLevel - 1][index]) != 0)
+ if (count >= 64)
{
- return false;
+ int remaining = count;
+ int tempIdx = index;
+
+ do
+ {
+ if (Masks[MaxLevel - 1][tempIdx++] != -1L)
+ {
+ return false;
+ }
+
+ remaining -= 64;
+ }
+ while (remaining != 0);
+
+ remaining = count;
+ tempIdx = index;
+
+ do
+ {
+ Masks[MaxLevel - 1][tempIdx] = 0;
+
+ ClearMaskBit(MaxLevel - 2, tempIdx++);
+
+ remaining -= 64;
+ }
+ while (remaining != 0);
}
+ else
+ {
+ long value = Masks[MaxLevel - 1][index];
+
+ if ((mask & ~value) != 0)
+ {
+ return false;
+ }
- Masks[MaxLevel - 1][index] &= ~mask;
+ value &= ~mask;
- for (int level = MaxLevel - 2; level >= 0; level--, index /= 64)
+ Masks[MaxLevel - 1][index] = value;
+
+ if (value == 0)
+ {
+ ClearMaskBit(MaxLevel - 2, index);
+ }
+ }
+
+ FreeCount -= (ulong)count;
+
+ return true;
+ }
+
+ public void ClearMaskBit(int startLevel, int index)
+ {
+ for (int level = startLevel; level >= 0; level--, index /= 64)
{
Masks[level][index / 64] &= ~(1L << (index & 63));
@@ -34,10 +82,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
break;
}
}
-
- FreeCount -= (ulong)size;
-
- return true;
}
}
} \ No newline at end of file