diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-09-18 12:28:28 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-18 12:28:28 -0300 |
| commit | d6fba62f8ac89cff76832d6e2cfe5a7a82e1ff1d (patch) | |
| tree | 82b82f481524333fba5134d8dd617a73977a5efd | |
| parent | d4187aaa9d7194aa26d04aee838edbc3a38f1862 (diff) | |
Misc fixes on the arena allocator (#364)
| -rw-r--r-- | Ryujinx.HLE/Memory/ArenaAllocator.cs | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/Ryujinx.HLE/Memory/ArenaAllocator.cs b/Ryujinx.HLE/Memory/ArenaAllocator.cs index 5e15f46a..9bcb7873 100644 --- a/Ryujinx.HLE/Memory/ArenaAllocator.cs +++ b/Ryujinx.HLE/Memory/ArenaAllocator.cs @@ -45,6 +45,33 @@ namespace Ryujinx.HLE.Memory Rg.Position += Size; Rg.Size -= Size; + if (Rg.Size == 0) + { + //Region is empty, just remove it. + FreeRegions.Remove(Node); + } + else if (Node.Previous != null) + { + //Re-sort based on size (smaller first). + Node = Node.Previous; + + FreeRegions.Remove(Node.Next); + + while (Node != null && (ulong)Node.Value.Size > (ulong)Rg.Size) + { + Node = Node.Previous; + } + + if (Node != null) + { + FreeRegions.AddAfter(Node, Rg); + } + else + { + FreeRegions.AddFirst(Rg); + } + } + TotalUsedSize += Size; return true; @@ -65,7 +92,7 @@ namespace Ryujinx.HLE.Memory Region NewRg = new Region(Position, Size); LinkedListNode<Region> Node = FreeRegions.First; - LinkedListNode<Region> PrevSz = Node; + LinkedListNode<Region> PrevSz = null; while (Node != null) { @@ -77,27 +104,38 @@ namespace Ryujinx.HLE.Memory if (Rg.Position == End) { + //Current region position matches the end of the freed region, + //just merge the two and remove the current region from the list. NewRg.Size += Rg.Size; FreeRegions.Remove(Node); } else if (RgEnd == Position) { + //End of the current region matches the position of the freed region, + //just merge the two and remove the current region from the list. NewRg.Position = Rg.Position; NewRg.Size += Rg.Size; FreeRegions.Remove(Node); } - else if ((ulong)Rg.Size < (ulong)NewRg.Size && - (ulong)Rg.Size > (ulong)PrevSz.Value.Size) + else { - PrevSz = Node; + if (PrevSz == null) + { + PrevSz = Node; + } + else if ((ulong)Rg.Size < (ulong)NewRg.Size && + (ulong)Rg.Size > (ulong)PrevSz.Value.Size) + { + PrevSz = Node; + } } Node = NextNode; } - if ((ulong)PrevSz.Value.Size < (ulong)Size) + if (PrevSz != null && (ulong)PrevSz.Value.Size < (ulong)Size) { FreeRegions.AddAfter(PrevSz, NewRg); } |
