Tests.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using NUnit.Framework;
  2. using Ryujinx.Memory;
  3. using System;
  4. using System.Runtime.InteropServices;
  5. namespace Ryujinx.Tests.Memory
  6. {
  7. public class Tests
  8. {
  9. private static readonly ulong _memorySize = MemoryBlock.GetPageSize() * 8;
  10. private MemoryBlock _memoryBlock;
  11. [SetUp]
  12. public void Setup()
  13. {
  14. _memoryBlock = new MemoryBlock(_memorySize);
  15. }
  16. [TearDown]
  17. public void Teardown()
  18. {
  19. _memoryBlock.Dispose();
  20. }
  21. [Test]
  22. public void Test_Read()
  23. {
  24. Marshal.WriteInt32(_memoryBlock.Pointer, 0x2020, 0x1234abcd);
  25. Assert.AreEqual(_memoryBlock.Read<int>(0x2020), 0x1234abcd);
  26. }
  27. [Test]
  28. public void Test_Write()
  29. {
  30. _memoryBlock.Write(0x2040, 0xbadc0de);
  31. Assert.AreEqual(Marshal.ReadInt32(_memoryBlock.Pointer, 0x2040), 0xbadc0de);
  32. }
  33. [Test]
  34. // Memory aliasing tests fail on CI at the moment.
  35. [Platform(Exclude = "MacOsX")]
  36. public void Test_Alias()
  37. {
  38. ulong pageSize = MemoryBlock.GetPageSize();
  39. ulong blockSize = MemoryBlock.GetPageSize() * 16;
  40. using MemoryBlock backing = new(blockSize, MemoryAllocationFlags.Mirrorable);
  41. using MemoryBlock toAlias = new(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
  42. toAlias.MapView(backing, pageSize, 0, pageSize * 4);
  43. toAlias.UnmapView(backing, pageSize * 3, pageSize);
  44. toAlias.Write(0, 0xbadc0de);
  45. Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de);
  46. }
  47. [Test]
  48. // Memory aliasing tests fail on CI at the moment.
  49. [Platform(Exclude = "MacOsX")]
  50. public void Test_AliasRandom()
  51. {
  52. ulong pageSize = MemoryBlock.GetPageSize();
  53. int pageBits = (int)ulong.Log2(pageSize);
  54. ulong blockSize = MemoryBlock.GetPageSize() * 128;
  55. using MemoryBlock backing = new(blockSize, MemoryAllocationFlags.Mirrorable);
  56. using MemoryBlock toAlias = new(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
  57. Random rng = new(123);
  58. for (int i = 0; i < 20000; i++)
  59. {
  60. int srcPage = rng.Next(0, 64);
  61. int dstPage = rng.Next(0, 64);
  62. int pages = rng.Next(1, 65);
  63. if ((rng.Next() & 1) != 0)
  64. {
  65. toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
  66. int offset = rng.Next(0, (int)pageSize - sizeof(int));
  67. toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de);
  68. Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de);
  69. }
  70. else
  71. {
  72. toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
  73. }
  74. }
  75. }
  76. [Test]
  77. // Memory aliasing tests fail on CI at the moment.
  78. [Platform(Exclude = "MacOsX")]
  79. public void Test_AliasMapLeak()
  80. {
  81. ulong pageSize = MemoryBlock.GetPageSize();
  82. ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
  83. using MemoryBlock backing = new(pageSize, MemoryAllocationFlags.Mirrorable);
  84. using MemoryBlock toAlias = new(size, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
  85. for (ulong offset = 0; offset < size; offset += pageSize)
  86. {
  87. toAlias.MapView(backing, 0, offset, pageSize);
  88. toAlias.Write(offset, 0xbadc0de);
  89. Assert.AreEqual(0xbadc0de, backing.Read<int>(0));
  90. toAlias.UnmapView(backing, offset, pageSize);
  91. }
  92. }
  93. }
  94. }