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