Browse Source

MemoryAllocatorOptions -> MemoryAllocatorSettings,

remove MinimumContiguousBlockSizeBytes
af/UniformUnmanagedMemoryPoolMemoryAllocator-02-MemoryGuards
Anton Firszov 5 years ago
parent
commit
2472c4285b
  1. 2
      src/ImageSharp/ImageFrame{TPixel}.cs
  2. 8
      src/ImageSharp/Memory/Allocators/MemoryAllocator.cs
  3. 57
      src/ImageSharp/Memory/Allocators/MemoryAllocatorOptions.cs
  4. 31
      src/ImageSharp/Memory/Allocators/MemoryAllocatorSettings.cs
  5. 6
      src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
  6. 22
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs

2
src/ImageSharp/ImageFrame{TPixel}.cs

@ -217,7 +217,7 @@ namespace SixLabors.ImageSharp
/// <para />
/// To ensure the memory is contiguous, <see cref="Configuration.MemoryAllocator"/> should be initialized
/// with a <see cref="MemoryAllocator"/> that enforces larger contiguous buffers.
/// See <see cref="MemoryAllocatorOptions.MinimumContiguousBlockSizeBytes"/>.
/// See <see cref="MemoryAllocatorSettings.MinimumContiguousBlockSizeBytes"/>.
/// <para />
/// WARNING: Disposing or leaking the underlying image while still working with it's <see cref="Span{T}"/>
/// might lead to memory corruption.

8
src/ImageSharp/Memory/Allocators/MemoryAllocator.cs

@ -22,15 +22,15 @@ namespace SixLabors.ImageSharp.Memory
/// </summary>
/// <returns>The <see cref="MemoryAllocator"/>.</returns>
public static MemoryAllocator CreateDefault() =>
new UniformUnmanagedMemoryPoolMemoryAllocator(null, null);
new UniformUnmanagedMemoryPoolMemoryAllocator(null);
/// <summary>
/// Creates the default <see cref="MemoryAllocator"/> using the provided options.
/// </summary>
/// <param name="options">The <see cref="MemoryAllocatorOptions"/>.</param>
/// <param name="settings">The <see cref="MemoryAllocatorSettings"/>.</param>
/// <returns>The <see cref="MemoryAllocator"/>.</returns>
public static MemoryAllocator CreateDefault(MemoryAllocatorOptions options) =>
new UniformUnmanagedMemoryPoolMemoryAllocator(options.MaximumPoolSizeMegabytes, options.MinimumContiguousBlockSizeBytes);
public static MemoryAllocator CreateDefault(MemoryAllocatorSettings settings) =>
new UniformUnmanagedMemoryPoolMemoryAllocator(settings.MaximumPoolSizeMegabytes);
/// <summary>
/// Allocates an <see cref="IMemoryOwner{T}" />, holding a <see cref="Memory{T}"/> of length <paramref name="length"/>.

57
src/ImageSharp/Memory/Allocators/MemoryAllocatorOptions.cs

@ -1,57 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Memory
{
/// <summary>
/// Defines options for creating the default <see cref="MemoryAllocator"/>.
/// </summary>
public class MemoryAllocatorOptions
{
private int? maximumPoolSizeMegabytes;
private int? minimumContiguousBlockSizeBytes;
/// <summary>
/// Gets or sets a value defining the maximum size of the <see cref="MemoryAllocator"/>'s internal memory pool
/// in Megabytes. <see langword="null"/> means platform default.
/// </summary>
public int? MaximumPoolSizeMegabytes
{
get => this.maximumPoolSizeMegabytes;
set
{
if (value.HasValue)
{
Guard.MustBeGreaterThanOrEqualTo(value.Value, 0, nameof(this.MaximumPoolSizeMegabytes));
}
this.maximumPoolSizeMegabytes = value;
}
}
/// <summary>
/// Gets or sets a value defining the minimum contiguous block size when allocating buffers for
/// <see cref="MemoryGroup{T}"/>, <see cref="Buffer2D{T}"/> or <see cref="Image{TPixel}"/>.
/// <see langword="null"/> means platform default.
/// </summary>
/// <remarks>
/// Overriding this value is useful for interop scenarios
/// ensuring <see cref="Image{TPixel}.TryGetSinglePixelSpan"/> succeeds.
/// </remarks>
public int? MinimumContiguousBlockSizeBytes
{
get => this.minimumContiguousBlockSizeBytes;
set
{
if (value.HasValue)
{
// It doesn't make sense to set this to small values in practice.
// Defining an arbitrary minimum of 65536.
Guard.MustBeGreaterThanOrEqualTo(value.Value, 65536, nameof(this.MaximumPoolSizeMegabytes));
}
this.minimumContiguousBlockSizeBytes = value;
}
}
}
}

31
src/ImageSharp/Memory/Allocators/MemoryAllocatorSettings.cs

@ -0,0 +1,31 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Memory
{
/// <summary>
/// Defines options for creating the default <see cref="MemoryAllocator"/>.
/// </summary>
public class MemoryAllocatorSettings
{
private int? maximumPoolSizeMegabytes;
/// <summary>
/// Gets or sets a value defining the maximum size of the <see cref="MemoryAllocator"/>'s internal memory pool
/// in Megabytes. <see langword="null"/> means platform default.
/// </summary>
public int? MaximumPoolSizeMegabytes
{
get => this.maximumPoolSizeMegabytes;
set
{
if (value.HasValue)
{
Guard.MustBeGreaterThanOrEqualTo(value.Value, 0, nameof(this.MaximumPoolSizeMegabytes));
}
this.maximumPoolSizeMegabytes = value;
}
}
}
}

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

@ -25,11 +25,11 @@ namespace SixLabors.ImageSharp.Memory
private UniformUnmanagedMemoryPool pool;
private readonly UnmanagedMemoryAllocator nonPoolAllocator;
public UniformUnmanagedMemoryPoolMemoryAllocator(int? maxPoolSizeMegabytes, int? minimumContiguousBlockBytes)
public UniformUnmanagedMemoryPoolMemoryAllocator(int? maxPoolSizeMegabytes)
: this(
minimumContiguousBlockBytes.HasValue ? minimumContiguousBlockBytes.Value : DefaultContiguousPoolBlockSizeBytes,
DefaultContiguousPoolBlockSizeBytes,
maxPoolSizeMegabytes.HasValue ? (long)maxPoolSizeMegabytes.Value * OneMegabyte : GetDefaultMaxPoolSizeBytes(),
minimumContiguousBlockBytes.HasValue ? Math.Max(minimumContiguousBlockBytes.Value, DefaultNonPoolBlockSizeBytes) : DefaultNonPoolBlockSizeBytes)
DefaultNonPoolBlockSizeBytes)
{
}

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

@ -145,28 +145,6 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void MemoryAllocator_CreateDefault_WithOptions_CanForceContiguousAllocation(bool poolAllocation)
{
RemoteExecutor.Invoke(RunTest, poolAllocation.ToString()).Dispose();
static void RunTest(string poolAllocationStr)
{
int fortyEightMegabytes = 48 * (1 << 20);
var allocator = MemoryAllocator.CreateDefault(new MemoryAllocatorOptions()
{
MaximumPoolSizeMegabytes = bool.Parse(poolAllocationStr) ? 64 : 0,
MinimumContiguousBlockSizeBytes = fortyEightMegabytes
});
MemoryGroup<byte> g = allocator.AllocateGroup<byte>(fortyEightMegabytes, 1024);
Assert.Equal(1, g.Count);
Assert.Equal(fortyEightMegabytes, g.TotalLength);
}
}
[Theory]
[InlineData(true)]
[InlineData(false)]

Loading…
Cancel
Save