KMemoryRegionBlock.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. namespace Ryujinx.HLE.HOS.Kernel.Memory
  2. {
  3. class KMemoryRegionBlock
  4. {
  5. public long[][] Masks;
  6. public ulong FreeCount;
  7. public int MaxLevel;
  8. public ulong StartAligned;
  9. public ulong SizeInBlocksTruncated;
  10. public ulong SizeInBlocksRounded;
  11. public int Order;
  12. public int NextOrder;
  13. public bool TryCoalesce(int index, int count)
  14. {
  15. long mask = ((1L << count) - 1) << (index & 63);
  16. index /= 64;
  17. if (count >= 64)
  18. {
  19. int remaining = count;
  20. int tempIdx = index;
  21. do
  22. {
  23. if (Masks[MaxLevel - 1][tempIdx++] != -1L)
  24. {
  25. return false;
  26. }
  27. remaining -= 64;
  28. }
  29. while (remaining != 0);
  30. remaining = count;
  31. tempIdx = index;
  32. do
  33. {
  34. Masks[MaxLevel - 1][tempIdx] = 0;
  35. ClearMaskBit(MaxLevel - 2, tempIdx++);
  36. remaining -= 64;
  37. }
  38. while (remaining != 0);
  39. }
  40. else
  41. {
  42. long value = Masks[MaxLevel - 1][index];
  43. if ((mask & ~value) != 0)
  44. {
  45. return false;
  46. }
  47. value &= ~mask;
  48. Masks[MaxLevel - 1][index] = value;
  49. if (value == 0)
  50. {
  51. ClearMaskBit(MaxLevel - 2, index);
  52. }
  53. }
  54. FreeCount -= (ulong)count;
  55. return true;
  56. }
  57. public void ClearMaskBit(int startLevel, int index)
  58. {
  59. for (int level = startLevel; level >= 0; level--, index /= 64)
  60. {
  61. Masks[level][index / 64] &= ~(1L << (index & 63));
  62. if (Masks[level][index / 64] != 0)
  63. {
  64. break;
  65. }
  66. }
  67. }
  68. }
  69. }