📷 A modern, cross-platform, 2D Graphics library for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
2.4 KiB

// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Diagnostics;
namespace SixLabors.ImageSharp.Tests;
public static class MemoryAllocatorValidator
{
private static readonly AsyncLocal<TestMemoryDiagnostics> LocalInstance = new();
public static bool MonitoringAllocations => LocalInstance.Value != null;
static MemoryAllocatorValidator()
{
MemoryDiagnostics.MemoryAllocated += MemoryDiagnostics_MemoryAllocated;
MemoryDiagnostics.MemoryReleased += MemoryDiagnostics_MemoryReleased;
}
private static void MemoryDiagnostics_MemoryReleased()
{
TestMemoryDiagnostics backing = LocalInstance.Value;
backing?.OnReleased();
}
private static void MemoryDiagnostics_MemoryAllocated()
{
TestMemoryDiagnostics backing = LocalInstance.Value;
backing?.OnAllocated();
}
public static TestMemoryDiagnostics MonitorAllocations()
{
TestMemoryDiagnostics diag = new();
LocalInstance.Value = diag;
return diag;
}
public static void StopMonitoringAllocations() => LocalInstance.Value = null;
public static void ValidateAllocations(int expectedAllocationCount = 0)
=> LocalInstance.Value?.Validate(expectedAllocationCount);
public sealed class TestMemoryDiagnostics : IDisposable
{
private int totalAllocated;
private int totalRemainingAllocated;
public int TotalAllocated => Volatile.Read(ref this.totalAllocated);
public int TotalRemainingAllocated => Volatile.Read(ref this.totalRemainingAllocated);
internal void OnAllocated()
{
Interlocked.Increment(ref this.totalAllocated);
Interlocked.Increment(ref this.totalRemainingAllocated);
}
internal void OnReleased()
=> Interlocked.Decrement(ref this.totalRemainingAllocated);
public void Validate(int expectedAllocationCount)
{
int count = this.TotalRemainingAllocated;
bool pass = expectedAllocationCount == count;
Assert.True(pass, $"Expected {expectedAllocationCount} undisposed buffers but found {count}");
}
public void Dispose()
{
this.Validate(0);
if (LocalInstance.Value == this)
{
StopMonitoringAllocations();
}
}
}
}