Misc fixes on the arena allocator (#364)

This commit is contained in:
gdkchan 2018-09-18 12:28:28 -03:00 committed by GitHub
parent d4187aaa9d
commit d6fba62f8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -45,6 +45,33 @@ namespace Ryujinx.HLE.Memory
Rg.Position += Size; Rg.Position += Size;
Rg.Size -= 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; TotalUsedSize += Size;
return true; return true;
@ -65,7 +92,7 @@ namespace Ryujinx.HLE.Memory
Region NewRg = new Region(Position, Size); Region NewRg = new Region(Position, Size);
LinkedListNode<Region> Node = FreeRegions.First; LinkedListNode<Region> Node = FreeRegions.First;
LinkedListNode<Region> PrevSz = Node; LinkedListNode<Region> PrevSz = null;
while (Node != null) while (Node != null)
{ {
@ -77,27 +104,38 @@ namespace Ryujinx.HLE.Memory
if (Rg.Position == End) 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; NewRg.Size += Rg.Size;
FreeRegions.Remove(Node); FreeRegions.Remove(Node);
} }
else if (RgEnd == Position) 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.Position = Rg.Position;
NewRg.Size += Rg.Size; NewRg.Size += Rg.Size;
FreeRegions.Remove(Node); FreeRegions.Remove(Node);
} }
else if ((ulong)Rg.Size < (ulong)NewRg.Size && else
(ulong)Rg.Size > (ulong)PrevSz.Value.Size)
{ {
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; Node = NextNode;
} }
if ((ulong)PrevSz.Value.Size < (ulong)Size) if (PrevSz != null && (ulong)PrevSz.Value.Size < (ulong)Size)
{ {
FreeRegions.AddAfter(PrevSz, NewRg); FreeRegions.AddAfter(PrevSz, NewRg);
} }