From bcc5b0d21ec68732c3db37147e07800e3851892a Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 25 Apr 2020 10:25:22 -0300 Subject: [PATCH] Fix kernel memory allocator block coalescing (#1155) * Fix kernel memory allocator block coalescing * Fix and move clear bit logic to a separate method --- .../HOS/Kernel/Memory/KMemoryRegionBlock.cs | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionBlock.cs index 3334ff439a..9a77349522 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; + } + + value &= ~mask; + + Masks[MaxLevel - 1][index] = value; + + if (value == 0) + { + ClearMaskBit(MaxLevel - 2, index); + } } - Masks[MaxLevel - 1][index] &= ~mask; + FreeCount -= (ulong)count; - for (int level = MaxLevel - 2; level >= 0; level--, index /= 64) + 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