Adding back the byteOffset to OwnedMemory Pin (#2067)

This commit is contained in:
Ahson Khan 2018-01-24 18:58:14 -08:00 коммит произвёл GitHub
Родитель 3cb38284f2
Коммит 1183c2a37f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 111 добавлений и 62 удалений

Просмотреть файл

@ -1 +1 @@
2.2.0-preview1-008003
2.1.300-preview2-008018

Просмотреть файл

@ -1 +1 @@
2.1.0-preview1-26122-01
2.1.0-preview2-26124-05

Просмотреть файл

@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2020
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MultiSegmentBytesReaderNumbers", "MultiSegmentBytesReaderNumbers", "{5E7EB061-B9BC-4DA2-B5E5-859AA7C67695}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5E7EB061-B9BC-4DA2-B5E5-859AA7C67695}"
ProjectSection(SolutionItems) = preProject
global.json = global.json
NuGet.Config = NuGet.Config

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Buffers.Native;
using System.Runtime.CompilerServices;
namespace System.Buffers.Native
{
@ -41,10 +42,11 @@ namespace System.Buffers.Native
return false;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
Retain();
return new MemoryHandle(this, _pointer.ToPointer());
if (byteOffset < 0 || byteOffset > _length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
return new MemoryHandle(this, Unsafe.Add<byte>(_pointer.ToPointer(), byteOffset));
}
private readonly NativeMemoryPool _pool;

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Buffers.Native
@ -36,12 +37,13 @@ namespace System.Buffers.Native
_pointer = IntPtr.Zero;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
Retain();
if (byteOffset < 0 || byteOffset > _length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
unsafe
{
return new MemoryHandle(this, _pointer.ToPointer());
return new MemoryHandle(this, Unsafe.Add<byte>(_pointer.ToPointer(), byteOffset));
}
}
protected override bool TryGetArray(out ArraySegment<byte> arraySegment)

Просмотреть файл

@ -59,9 +59,10 @@ namespace System.Buffers.Native
base.Dispose(disposing);
}
public unsafe override MemoryHandle Pin()
public unsafe override MemoryHandle Pin(int byteOffset = 0)
{
return new MemoryHandle(this, _pointer.ToPointer());
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
return new MemoryHandle(this, Unsafe.Add<byte>(_pointer.ToPointer(), byteOffset));
}
protected override bool TryGetArray(out ArraySegment<T> arraySegment)

Просмотреть файл

@ -20,7 +20,7 @@ namespace System.Buffers
public OwnedArray(T[] array)
{
if (array == null) ThrowArgumentNullException(nameof(array));
if (array == null) ThrowArgumentNullException(nameof(array));
_array = array;
}
@ -37,13 +37,15 @@ namespace System.Buffers
}
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain();
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle);
void* pointer = Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), byteOffset);
return new MemoryHandle(this, pointer, handle);
}
}
@ -68,7 +70,7 @@ namespace System.Buffers
public override bool Release()
{
int newRefCount = Interlocked.Decrement(ref _referenceCount);
if (newRefCount < 0) ThrowInvalidOperationException();
if (newRefCount < 0) ThrowInvalidOperationException();
if (newRefCount == 0)
{
OnNoReferences();

Просмотреть файл

@ -33,7 +33,7 @@ namespace System.Buffers.Internal
T[] _array;
bool _disposed;
int _referenceCount;
public ArrayPoolMemory(int size)
{
_array = ArrayPool<T>.Shared.Rent(size);
@ -57,7 +57,8 @@ namespace System.Buffers.Internal
protected override void Dispose(bool disposing)
{
var array = Interlocked.Exchange(ref _array, null);
if (array != null) {
if (array != null)
{
_disposed = true;
ArrayPool<T>.Shared.Return(array);
}
@ -70,13 +71,15 @@ namespace System.Buffers.Internal
return true;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain(); // this checks IsDisposed
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle);
void* pointer = Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), byteOffset);
return new MemoryHandle(this, pointer, handle);
}
}
@ -90,7 +93,7 @@ namespace System.Buffers.Internal
{
int newRefCount = Interlocked.Decrement(ref _referenceCount);
if (newRefCount < 0) throw new InvalidOperationException();
if (newRefCount == 0)
if (newRefCount == 0)
{
Dispose();
return false;

Просмотреть файл

@ -116,8 +116,8 @@ namespace System.Buffers
if (newRefCount < 0) RioPipelinesThrowHelper.ThrowInvalidOperationException(ExceptionResource.ReferenceCountZero);
if (newRefCount == 0)
{
OnZeroReferences();
return false;
OnZeroReferences();
return false;
}
return true;
}
@ -134,13 +134,13 @@ namespace System.Buffers
return true;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
if (IsDisposed) RioPipelinesThrowHelper.ThrowObjectDisposedException(nameof(RioMemoryPoolBlock));
Retain();
Retain(); // checks IsDisposed
if (byteOffset < 0 || byteOffset > _length) RioPipelinesThrowHelper.ThrowArgumentOutOfRangeException(_length, byteOffset);
unsafe
{
return new MemoryHandle(this, (Slab.NativePointer + _offset).ToPointer());
return new MemoryHandle(this, (Slab.NativePointer + _offset + byteOffset).ToPointer());
}
}
}

Просмотреть файл

@ -7,12 +7,30 @@ using System.Runtime.CompilerServices;
namespace System.IO.Pipelines
{
internal class RioPipelinesThrowHelper
{
{
public static void ThrowArgumentOutOfRangeException(int sourceLength, int offset)
{
throw GetArgumentOutOfRangeException(sourceLength, offset);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(int sourceLength, int offset)
{
if ((uint)offset > (uint)sourceLength)
{
// Offset is negative or less than array length
return new ArgumentOutOfRangeException(GetArgumentName(ExceptionArgument.offset));
}
// The third parameter (not passed) length must be out of range
return new ArgumentOutOfRangeException(GetArgumentName(ExceptionArgument.length));
}
public static void ThrowInvalidOperationException(ExceptionResource resource, string location = null)
{
throw GetInvalidOperationException(resource, location);
}
public static void ThrowArgumentOutOfRangeException_BufferRequestTooLarge(int maxSize)
{
throw GetArgumentOutOfRangeException_BufferRequestTooLarge(maxSize);
@ -28,7 +46,7 @@ namespace System.IO.Pipelines
{
return new InvalidOperationException(GetResourceString(resource, location));
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static ArgumentOutOfRangeException GetArgumentOutOfRangeException_BufferRequestTooLarge(int maxSize)
{

Просмотреть файл

@ -116,8 +116,8 @@ namespace System.Buffers
if (newRefCount < 0) PipelinesThrowHelper.ThrowInvalidOperationException(ExceptionResource.ReferenceCountZero);
if (newRefCount == 0)
{
OnZeroReferences();
return false;
OnZeroReferences();
return false;
}
return true;
}
@ -134,13 +134,13 @@ namespace System.Buffers
return true;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
if (IsDisposed) PipelinesThrowHelper.ThrowObjectDisposedException(nameof(MemoryPoolBlock));
Retain();
Retain(); // checks IsDisposed
if (byteOffset < 0 || byteOffset > _length) PipelinesThrowHelper.ThrowArgumentOutOfRangeException(_length, byteOffset);
unsafe
{
return new MemoryHandle(this, (Slab.NativePointer + _offset).ToPointer());
return new MemoryHandle(this, (Slab.NativePointer + _offset + byteOffset).ToPointer());
}
}
}

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Buffers.Native;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@ -12,8 +13,9 @@ namespace System.Buffers.Tests
{
[Fact]
public void SimpleTests()
{
using(var owned = new OwnedNativeBuffer(1024)) {
{
using (var owned = new OwnedNativeBuffer(1024))
{
var span = owned.Span;
span[10] = 10;
unsafe { Assert.Equal(10, owned.Pointer[10]); }
@ -28,7 +30,8 @@ namespace System.Buffers.Tests
Assert.Equal(10, copy[0]);
}
using (OwnedPinnedBuffer<byte> owned = new byte[1024]) {
using (OwnedPinnedBuffer<byte> owned = new byte[1024])
{
var span = owned.Span;
span[10] = 10;
Assert.Equal(10, owned.Array[10]);
@ -57,33 +60,40 @@ namespace System.Buffers.Tests
public unsafe void PinnedArrayMemoryLifetime()
{
var bytes = new byte[1024];
fixed (byte* pBytes = bytes) {
fixed (byte* pBytes = bytes)
{
var owner = new OwnedPinnedBuffer<byte>(bytes, pBytes);
TestLifetime(owner);
TestLifetime(owner);
}
}
static void TestLifetime(OwnedMemory<byte> owned)
{
Memory<byte> copyStoredForLater;
try {
try
{
Memory<byte> memory = owned.Memory;
Memory<byte> memorySlice = memory.Slice(10);
copyStoredForLater = memorySlice;
var r = memorySlice.Retain();
try {
Assert.Throws<InvalidOperationException>(() => { // memory is reserved; premature dispose check fires
try
{
Assert.Throws<InvalidOperationException>(() =>
{ // memory is reserved; premature dispose check fires
owned.Dispose();
});
}
finally {
finally
{
r.Dispose(); // release reservation
}
}
finally {
finally
{
owned.Dispose(); // can finish dispose with no exception
}
Assert.Throws<ObjectDisposedException>(() => {
Assert.Throws<ObjectDisposedException>(() =>
{
// memory is disposed; cannot use copy stored for later
var span = copyStoredForLater.Span;
});
@ -110,7 +120,7 @@ namespace System.Buffers.Tests
var owned = new CustomBuffer<byte>(255);
var memory = owned.Memory;
Assert.Equal(0, owned.OnNoRefencesCalledCount);
using (memory.Retain())
{
Assert.Equal(0, owned.OnNoRefencesCalledCount);
@ -136,7 +146,8 @@ namespace System.Buffers.Tests
memories[i] = owners[i].Memory;
}
var dispose_task = Task.Run(() => {
var dispose_task = Task.Run(() =>
{
for (int i = 0; i < owners.Length; i++)
{
try
@ -151,7 +162,8 @@ namespace System.Buffers.Tests
}
});
var reserve_task = Task.Run(() => {
var reserve_task = Task.Run(() =>
{
for (int i = owners.Length - 1; i >= 0; i--)
{
try
@ -205,13 +217,15 @@ namespace System.Buffers.Tests
}
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain();
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle);
void* pointer = Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), byteOffset);
return new MemoryHandle(this, pointer, handle);
}
}
@ -240,8 +254,8 @@ namespace System.Buffers.Tests
if (newRefCount < 0) throw new InvalidOperationException();
if (newRefCount == 0)
{
_noReferencesCalledCount++;
return false;
_noReferencesCalledCount++;
return false;
}
return true;
}
@ -283,13 +297,15 @@ namespace System.Buffers.Tests
return true;
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain();
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle);
void* pointer = Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), byteOffset);
return new MemoryHandle(this, pointer, handle);
}
}

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
@ -38,13 +39,15 @@ namespace System.Buffers.Tests
}
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain();
if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf<T>()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
var handle = GCHandle.Alloc(_array, GCHandleType.Pinned);
return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle);
void* pointer = Unsafe.Add<byte>((void*)handle.AddrOfPinnedObject(), byteOffset);
return new MemoryHandle(this, pointer, handle);
}
}

Просмотреть файл

@ -151,7 +151,7 @@ namespace System.IO.Pipelines.Tests
}
}
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
throw new NotImplementedException();
}

Просмотреть файл

@ -44,12 +44,14 @@ namespace System.Numerics.Tensors.Tests
protected override bool IsRetained => refCount > 0;
public override MemoryHandle Pin()
public override MemoryHandle Pin(int byteOffset = 0)
{
unsafe
{
Retain();
return new MemoryHandle(this, (void*)memory);
if (byteOffset < 0 || (byteOffset / Marshal.SizeOf<T>()) > length) throw new ArgumentOutOfRangeException(nameof(byteOffset));
void* pointer = (void*)((byte*)memory + byteOffset);
return new MemoryHandle(this, pointer);
}
}

Просмотреть файл

@ -1,11 +1,11 @@
<Project>
<PropertyGroup>
<RuntimeFrameworkVersion>2.1.0-preview1-26122-01</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion>2.1.0-preview2-26124-05</RuntimeFrameworkVersion>
<CoreFxStableVersion>4.3.0</CoreFxStableVersion>
<RoslynVersion>2.6.0-beta3-62316-02</RoslynVersion>
<SystemMemoryVersion>4.5.0-preview1-26122-01</SystemMemoryVersion>
<SystemCompilerServicesUnsafeVersion>4.5.0-preview1-26122-01</SystemCompilerServicesUnsafeVersion>
<SystemNumericsVectorsVersion>4.5.0-preview1-26122-01</SystemNumericsVectorsVersion>
<SystemMemoryVersion>4.5.0-preview2-26124-02</SystemMemoryVersion>
<SystemCompilerServicesUnsafeVersion>4.5.0-preview2-26124-02</SystemCompilerServicesUnsafeVersion>
<SystemNumericsVectorsVersion>4.5.0-preview2-26124-02</SystemNumericsVectorsVersion>
<LibuvVersion>1.9.1</LibuvVersion>
<TestSdkVersion>15.0.0</TestSdkVersion>
<XunitVersion>2.2.0</XunitVersion>