Misc fixes on the arena allocator (#364)
This commit is contained in:
parent
d4187aaa9d
commit
d6fba62f8a
1 changed files with 43 additions and 5 deletions
|
@ -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 (PrevSz == null)
|
||||||
|
{
|
||||||
|
PrevSz = Node;
|
||||||
|
}
|
||||||
else if ((ulong)Rg.Size < (ulong)NewRg.Size &&
|
else if ((ulong)Rg.Size < (ulong)NewRg.Size &&
|
||||||
(ulong)Rg.Size > (ulong)PrevSz.Value.Size)
|
(ulong)Rg.Size > (ulong)PrevSz.Value.Size)
|
||||||
{
|
{
|
||||||
PrevSz = Node;
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue