aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-09-18 12:28:28 -0300
committerGitHub <noreply@github.com>2018-09-18 12:28:28 -0300
commitd6fba62f8ac89cff76832d6e2cfe5a7a82e1ff1d (patch)
tree82b82f481524333fba5134d8dd617a73977a5efd
parentd4187aaa9d7194aa26d04aee838edbc3a38f1862 (diff)
Misc fixes on the arena allocator (#364)
-rw-r--r--Ryujinx.HLE/Memory/ArenaAllocator.cs48
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);
}