diff options
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs')
-rw-r--r-- | src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs new file mode 100644 index 00000000..0fde495c --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs @@ -0,0 +1,61 @@ +using Ryujinx.HLE.HOS.Kernel.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Process +{ + class KTlsPageManager + { + private const int TlsEntrySize = 0x200; + + private long _pagePosition; + + private int _usedSlots; + + private bool[] _slots; + + public bool IsEmpty => _usedSlots == 0; + public bool IsFull => _usedSlots == _slots.Length; + + public KTlsPageManager(long pagePosition) + { + _pagePosition = pagePosition; + + _slots = new bool[KPageTableBase.PageSize / TlsEntrySize]; + } + + public bool TryGetFreeTlsAddr(out long position) + { + position = _pagePosition; + + for (int index = 0; index < _slots.Length; index++) + { + if (!_slots[index]) + { + _slots[index] = true; + + _usedSlots++; + + return true; + } + + position += TlsEntrySize; + } + + position = 0; + + return false; + } + + public void FreeTlsSlot(int slot) + { + if ((uint)slot > _slots.Length) + { + throw new ArgumentOutOfRangeException(nameof(slot)); + } + + _slots[slot] = false; + + _usedSlots--; + } + } +}
\ No newline at end of file |