Browse Source

Merge pull request #2025 from SixLabors/af/TotalAvailableMemoryBytes-workaround

Workaround GC.GetMemoryInfo() ARM32 issue
pull/2031/head
Anton Firszov 4 years ago
committed by GitHub
parent
commit
3259c941d9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
  2. 15
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs

20
src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs

@ -1,11 +1,10 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Buffers; using System.Buffers;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading;
using SixLabors.ImageSharp.Memory.Internals; using SixLabors.ImageSharp.Memory.Internals;
namespace SixLabors.ImageSharp.Memory namespace SixLabors.ImageSharp.Memory
@ -22,7 +21,7 @@ namespace SixLabors.ImageSharp.Memory
private readonly int poolCapacity; private readonly int poolCapacity;
private readonly UniformUnmanagedMemoryPool.TrimSettings trimSettings; private readonly UniformUnmanagedMemoryPool.TrimSettings trimSettings;
private UniformUnmanagedMemoryPool pool; private readonly UniformUnmanagedMemoryPool pool;
private readonly UnmanagedMemoryAllocator nonPoolAllocator; private readonly UnmanagedMemoryAllocator nonPoolAllocator;
public UniformUnmanagedMemoryPoolMemoryAllocator(int? maxPoolSizeMegabytes) public UniformUnmanagedMemoryPoolMemoryAllocator(int? maxPoolSizeMegabytes)
@ -74,6 +73,12 @@ namespace SixLabors.ImageSharp.Memory
this.nonPoolAllocator = new UnmanagedMemoryAllocator(unmanagedBufferSizeInBytes); this.nonPoolAllocator = new UnmanagedMemoryAllocator(unmanagedBufferSizeInBytes);
} }
#if NETCOREAPP3_1_OR_GREATER
// This delegate allows overriding the method returning the available system memory,
// so we can test our workaround for https://github.com/dotnet/runtime/issues/65466
internal static Func<long> GetTotalAvailableMemoryBytes { get; set; } = () => GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
#endif
/// <inheritdoc /> /// <inheritdoc />
protected internal override int GetBufferCapacityInBytes() => this.poolBufferSizeInBytes; protected internal override int GetBufferCapacityInBytes() => this.poolBufferSizeInBytes;
@ -152,8 +157,13 @@ namespace SixLabors.ImageSharp.Memory
// https://github.com/dotnet/runtime/issues/55126#issuecomment-876779327 // https://github.com/dotnet/runtime/issues/55126#issuecomment-876779327
if (Environment.Is64BitProcess || !RuntimeInformation.FrameworkDescription.StartsWith(".NET 5.0")) if (Environment.Is64BitProcess || !RuntimeInformation.FrameworkDescription.StartsWith(".NET 5.0"))
{ {
GCMemoryInfo info = GC.GetGCMemoryInfo(); long total = GetTotalAvailableMemoryBytes();
return info.TotalAvailableMemoryBytes / 8;
// Workaround for https://github.com/dotnet/runtime/issues/65466
if (total > 0)
{
return total / 8;
}
} }
#endif #endif

15
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs

@ -379,5 +379,20 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
g1.GetSpan()[0] = 42; g1.GetSpan()[0] = 42;
} }
} }
#if NETCOREAPP3_1_OR_GREATER
[Fact]
public void Issue2001_NegativeMemoryReportedByGc()
{
RemoteExecutor.Invoke(RunTest).Dispose();
static void RunTest()
{
// Emulate GC.GetGCMemoryInfo() issue https://github.com/dotnet/runtime/issues/65466
UniformUnmanagedMemoryPoolMemoryAllocator.GetTotalAvailableMemoryBytes = () => -402354176;
_ = MemoryAllocator.Create();
}
}
#endif
} }
} }

Loading…
Cancel
Save