|
|
@@ -449,5 +449,61 @@ namespace Ryujinx.Memory.Tests
|
|
|
|
|
|
handle.Dispose();
|
|
|
}
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void PreciseAction()
|
|
|
+ {
|
|
|
+ RegionHandle handle = _tracking.BeginTracking(0, PageSize);
|
|
|
+
|
|
|
+ (ulong address, ulong size, bool write)? preciseTriggered = null;
|
|
|
+ handle.RegisterPreciseAction((address, size, write) =>
|
|
|
+ {
|
|
|
+ preciseTriggered = (address, size, write);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ (ulong address, ulong size)? readTrackingTriggered = null;
|
|
|
+ handle.RegisterAction((address, size) =>
|
|
|
+ {
|
|
|
+ readTrackingTriggered = (address, size);
|
|
|
+ });
|
|
|
+
|
|
|
+ handle.Reprotect();
|
|
|
+
|
|
|
+ _tracking.VirtualMemoryEvent(0, 4, false, precise: true);
|
|
|
+
|
|
|
+ Assert.IsNull(readTrackingTriggered); // Hasn't been triggered - precise action returned true.
|
|
|
+ Assert.AreEqual(preciseTriggered, (0UL, 4UL, false)); // Precise action was triggered.
|
|
|
+
|
|
|
+ _tracking.VirtualMemoryEvent(0, 4, true, precise: true);
|
|
|
+
|
|
|
+ Assert.IsNull(readTrackingTriggered); // Still hasn't been triggered.
|
|
|
+ bool dirtyAfterPreciseActionTrue = handle.Dirty;
|
|
|
+ Assert.False(dirtyAfterPreciseActionTrue); // Not dirtied - precise action returned true.
|
|
|
+ Assert.AreEqual(preciseTriggered, (0UL, 4UL, true)); // Precise action was triggered.
|
|
|
+
|
|
|
+ // Handle is now dirty.
|
|
|
+ handle.Reprotect(true);
|
|
|
+ preciseTriggered = null;
|
|
|
+
|
|
|
+ _tracking.VirtualMemoryEvent(4, 4, true, precise: true);
|
|
|
+ Assert.AreEqual(preciseTriggered, (4UL, 4UL, true)); // Precise action was triggered even though handle was dirty.
|
|
|
+
|
|
|
+ handle.Reprotect();
|
|
|
+ handle.RegisterPreciseAction((address, size, write) =>
|
|
|
+ {
|
|
|
+ preciseTriggered = (address, size, write);
|
|
|
+
|
|
|
+ return false; // Now, we return false, which indicates that the regular read/write behaviours should trigger.
|
|
|
+ });
|
|
|
+
|
|
|
+ _tracking.VirtualMemoryEvent(8, 4, true, precise: true);
|
|
|
+
|
|
|
+ Assert.AreEqual(readTrackingTriggered, (8UL, 4UL)); // Read action triggered, as precise action returned false.
|
|
|
+ bool dirtyAfterPreciseActionFalse = handle.Dirty;
|
|
|
+ Assert.True(dirtyAfterPreciseActionFalse); // Dirtied, as precise action returned false.
|
|
|
+ Assert.AreEqual(preciseTriggered, (8UL, 4UL, true)); // Precise action was triggered.
|
|
|
+ }
|
|
|
}
|
|
|
}
|