Optimize kernel memory block lookup and consolidate RBTree implementations (#3410)

* Implement intrusive red-black tree, use it for HLE kernel block manager

* Implement TreeDictionary using IntrusiveRedBlackTree

* Implement IntervalTree using IntrusiveRedBlackTree

* Implement IntervalTree (on Ryujinx.Memory) using IntrusiveRedBlackTree

* Make PredecessorOf and SuccessorOf internal, expose Predecessor and Successor properties on the node itself

* Allocation free tree node lookup
This commit is contained in:
gdkchan 2022-08-26 15:21:48 -03:00 committed by GitHub
parent 6592d64751
commit 6922862db8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 860 additions and 1121 deletions

View file

@ -2447,9 +2447,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{
ulong endAddr = address + size;
LinkedListNode<KMemoryBlock> node = _blockManager.FindBlockNode(address);
KMemoryBlock currBlock = _blockManager.FindBlock(address);
KMemoryInfo info = node.Value.GetInfo();
KMemoryInfo info = currBlock.GetInfo();
MemoryState firstState = info.State;
KMemoryPermission firstPermission = info.Permission;
@ -2457,7 +2457,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
do
{
info = node.Value.GetInfo();
info = currBlock.GetInfo();
// Check if the block state matches what we expect.
if (firstState != info.State ||
@ -2474,7 +2474,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return false;
}
}
while (info.Address + info.Size - 1 < endAddr - 1 && (node = node.Next) != null);
while (info.Address + info.Size - 1 < endAddr - 1 && (currBlock = currBlock.Successor) != null);
outState = firstState;
outPermission = firstPermission;
@ -2509,17 +2509,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
private IEnumerable<KMemoryInfo> IterateOverRange(ulong start, ulong end)
{
LinkedListNode<KMemoryBlock> node = _blockManager.FindBlockNode(start);
KMemoryBlock currBlock = _blockManager.FindBlock(start);
KMemoryInfo info;
do
{
info = node.Value.GetInfo();
info = currBlock.GetInfo();
yield return info;
}
while (info.Address + info.Size - 1 < end - 1 && (node = node.Next) != null);
while (info.Address + info.Size - 1 < end - 1 && (currBlock = currBlock.Successor) != null);
}
private ulong AllocateVa(ulong regionStart, ulong regionPagesCount, ulong neededPagesCount, int alignment)
@ -2605,9 +2605,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
ulong regionEndAddr = regionStart + regionPagesCount * PageSize;
LinkedListNode<KMemoryBlock> node = _blockManager.FindBlockNode(regionStart);
KMemoryBlock currBlock = _blockManager.FindBlock(regionStart);
KMemoryInfo info = node.Value.GetInfo();
KMemoryInfo info = currBlock.GetInfo();
while (regionEndAddr >= info.Address)
{
@ -2636,14 +2636,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
}
node = node.Next;
currBlock = currBlock.Successor;
if (node == null)
if (currBlock == null)
{
break;
}
info = node.Value.GetInfo();
info = currBlock.GetInfo();
}
return 0;