[Tests] Cover concurrent resolve answers and release device slabs

This commit is contained in:
ParantezTech 2026-10-11 06:11:56 +03:00
parent 6631a665f8
commit fab999316e
2 changed files with 76 additions and 0 deletions

View File

@ -161,6 +161,7 @@ internal sealed unsafe class HeadlessVulkan : IDisposable
public void Dispose()
{
Vk.DeviceWaitIdle(Device);
_deviceInfo?.Slabs.Destroy();
Vk.DestroyDevice(Device, null);
if (_debugUtils is { } debugUtils)
{

View File

@ -0,0 +1,75 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.Libs.VideoOut;
using Xunit;
using static SharpEmu.Libs.VideoOut.VulkanVideoPresenter;
namespace SharpEmu.Libs.Tests.VideoOut;
public sealed class ConcurrentResolveTests
{
[Fact]
public void ConsecutiveAndRepeatedReadsKeepOneProofPerQuery()
{
var assumptions = new ConcurrentAssumptions(1, 2);
assumptions.Record(ConcurrentQuery.ResidentClean, 0x1000, 4, false);
assumptions.Record(ConcurrentQuery.CleanWord, 0x1000, 4, false);
var allocated = GC.GetAllocatedBytesForCurrentThread();
for (var index = 0; index < 100000; index++)
{
var address = 0x1000UL + (ulong)index * 4;
assumptions.Record(ConcurrentQuery.ResidentClean, address, 4, false);
assumptions.Record(ConcurrentQuery.CleanWord, address, 4, false);
assumptions.Record(ConcurrentQuery.ResidentClean, address, 4, false);
}
Assert.Equal(allocated, GC.GetAllocatedBytesForCurrentThread());
Assert.Equal(2, assumptions.Answers.Count);
Assert.All(assumptions.Answers, proof =>
{
Assert.Equal(0x1000UL, proof.Address);
Assert.Equal(400000UL, proof.Size);
Assert.False(proof.Answer);
});
Assert.True(assumptions.ReadsImageOwnership);
}
[Fact]
public void OverlappingReadsMergeWithoutAddingUnreadGaps()
{
var assumptions = new ConcurrentAssumptions(1, 2);
assumptions.Record(ConcurrentQuery.DirtyBytes, 0x1020, 0x20, false);
assumptions.Record(ConcurrentQuery.DirtyBytes, 0x1000, 0x30, false);
assumptions.Record(ConcurrentQuery.DirtyBytes, 0x1050, 0x10, false);
Assert.Equal((ConcurrentQuery.DirtyBytes, 0x1000UL, 0x40UL, false), assumptions.Answers[0]);
Assert.Equal((ConcurrentQuery.DirtyBytes, 0x1050UL, 0x10UL, false), assumptions.Answers[1]);
Assert.False(assumptions.ReadsImageOwnership);
}
[Fact]
public void OwnedReadsAndDifferentOwnershipRulesRemainSeparate()
{
var assumptions = new ConcurrentAssumptions(1, 2);
assumptions.Record(ConcurrentQuery.Resident, 0x1000, 4, false);
assumptions.Record(ConcurrentQuery.ResidentClean, 0x1000, 4, false);
assumptions.Record(ConcurrentQuery.Resident, 0x1004, 4, true);
assumptions.Record(ConcurrentQuery.Resident, 0x1008, 4, true);
assumptions.Record(ConcurrentQuery.Resident, 0x1004, 4, true);
Assert.Equal(4, assumptions.Answers.Count);
Assert.Equal(2, assumptions.Answers.Count(proof => proof.Answer));
Assert.True(assumptions.ReadsImageOwnership);
}
[Fact]
public void WrappingRangesDoNotMergeWithLowAddresses()
{
var assumptions = new ConcurrentAssumptions(1, 2);
assumptions.Record(ConcurrentQuery.Resident, ulong.MaxValue - 1, 4, false);
assumptions.Record(ConcurrentQuery.Resident, 0, 4, false);
Assert.Equal(2, assumptions.Answers.Count);
}
}