Browse Source

MEMORY_SENTINEL

af/UniformUnmanagedMemoryPoolMemoryAllocator-02-MemoryGuards
Anton Firszov 5 years ago
parent
commit
a329a3a8a2
  1. 1
      src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs
  2. 6
      src/ImageSharp/Memory/Allocators/Internals/UnmanagedBuffer{T}.cs
  3. 30
      src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs

1
src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.Buffer{T}.cs

@ -26,6 +26,7 @@ namespace SixLabors.ImageSharp.Memory.Internals
return;
}
this.VerifyMemorySentinel();
this.pool.Return(this.BufferHandle);
this.pool = null;
this.BufferHandle = null;

6
src/ImageSharp/Memory/Allocators/Internals/UnmanagedBuffer{T}.cs

@ -3,6 +3,7 @@
using System;
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -61,10 +62,15 @@ namespace SixLabors.ImageSharp.Memory.Internals
return;
}
this.VerifyMemorySentinel();
if (disposing)
{
this.BufferHandle.Dispose();
}
}
[Conditional("MEMORY_SENTINEL")]
protected void VerifyMemorySentinel() => this.BufferHandle.VerifyMemorySentinel(this.lengthInElements * Unsafe.SizeOf<T>());
}
}

30
src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32.SafeHandles;
@ -24,6 +25,12 @@ namespace SixLabors.ImageSharp.Memory.Internals
// A Monitor to wait/signal when we are low on memory.
private static object lowMemoryMonitor;
#if MEMORY_SENTINEL
private const int MemorySentinelPadding = 16;
#else
private const int MemorySentinelPadding = 0;
#endif
private UnmanagedMemoryHandle(IntPtr handle, int lengthInBytes)
: base(handle, true)
{
@ -77,10 +84,31 @@ namespace SixLabors.ImageSharp.Memory.Internals
internal static UnmanagedMemoryHandle Allocate(int lengthInBytes)
{
IntPtr handle = AllocateHandle(lengthInBytes);
IntPtr handle = AllocateHandle(lengthInBytes + MemorySentinelPadding);
#if MEMORY_SENTINEL
unsafe
{
new Span<byte>((void*)handle, lengthInBytes + MemorySentinelPadding).Fill(42);
}
#endif
return new UnmanagedMemoryHandle(handle, lengthInBytes);
}
[Conditional("MEMORY_SENTINEL")]
internal unsafe void VerifyMemorySentinel(int actualLengthInBytes)
{
Span<byte> remainder =
new Span<byte>((void*)this.handle, this.lengthInBytes + MemorySentinelPadding)
.Slice(actualLengthInBytes);
for (int i = 0; i < remainder.Length; i++)
{
if (remainder[i] != 42)
{
throw new InvalidMemoryOperationException("Memory corruption detected!");
}
}
}
private static IntPtr AllocateHandle(int lengthInBytes)
{
int counter = 0;

Loading…
Cancel
Save