aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs')
-rw-r--r--src/Ryujinx.HLE/HOS/Kernel/Process/KTlsPageManager.cs61
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