KTlsPageInfo.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using Ryujinx.HLE.HOS.Kernel.Memory;
  2. namespace Ryujinx.HLE.HOS.Kernel.Process
  3. {
  4. class KTlsPageInfo
  5. {
  6. public const int TlsEntrySize = 0x200;
  7. public ulong PageVirtualAddress { get; }
  8. public ulong PagePhysicalAddress { get; }
  9. private readonly bool[] _isSlotFree;
  10. public KTlsPageInfo(ulong pageVirtualAddress, ulong pagePhysicalAddress)
  11. {
  12. PageVirtualAddress = pageVirtualAddress;
  13. PagePhysicalAddress = pagePhysicalAddress;
  14. _isSlotFree = new bool[KPageTableBase.PageSize / TlsEntrySize];
  15. for (int index = 0; index < _isSlotFree.Length; index++)
  16. {
  17. _isSlotFree[index] = true;
  18. }
  19. }
  20. public bool TryGetFreePage(out ulong address)
  21. {
  22. address = PageVirtualAddress;
  23. for (int index = 0; index < _isSlotFree.Length; index++)
  24. {
  25. if (_isSlotFree[index])
  26. {
  27. _isSlotFree[index] = false;
  28. return true;
  29. }
  30. address += TlsEntrySize;
  31. }
  32. address = 0;
  33. return false;
  34. }
  35. public bool IsFull()
  36. {
  37. bool hasFree = false;
  38. for (int index = 0; index < _isSlotFree.Length; index++)
  39. {
  40. hasFree |= _isSlotFree[index];
  41. }
  42. return !hasFree;
  43. }
  44. public bool IsEmpty()
  45. {
  46. bool allFree = true;
  47. for (int index = 0; index < _isSlotFree.Length; index++)
  48. {
  49. allFree &= _isSlotFree[index];
  50. }
  51. return allFree;
  52. }
  53. public void FreeTlsSlot(ulong address)
  54. {
  55. _isSlotFree[(address - PageVirtualAddress) / TlsEntrySize] = true;
  56. }
  57. }
  58. }