mirror of https://github.com/SixLabors/ImageSharp
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
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|