public static void NoPinAfterDispose() { OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42); block.Dispose(); Assert.Throws <ObjectDisposedException>(() => block.Pin()); }
public static void MemoryPoolPinOffsetAtEnd() { MemoryPool <int> pool = MemoryPool <int> .Shared; OwnedMemory <int> block = pool.Rent(10); Span <int> sp = block.Span; Assert.Equal(block.Length, sp.Length); int byteOffset = 0; try { byteOffset = checked (block.Length * sizeof(int)); } catch (OverflowException) { return; // The pool gave us a very large block - too big to compute the byteOffset needed to carry out this test. Skip. } using (MemoryHandle newMemoryHandle = block.Pin(byteOffset: byteOffset)) { unsafe { void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp)); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer) - byteOffset); } } }
static void DisposeAuto(OwnedMemory <byte> buffer) { var length = buffer.Length; buffer.Dispose(); Assert.True(buffer.IsDisposed); Assert.ThrowsAny <ObjectDisposedException>(() => { var ignore = buffer.Span; }); Assert.ThrowsAny <ObjectDisposedException>(() => { buffer.Span.Slice(0, length); }); Assert.ThrowsAny <ObjectDisposedException>(() => { buffer.Pin(); }); Assert.ThrowsAny <ObjectDisposedException>(() => { var rwBuffer = buffer.Memory; }); Assert.ThrowsAny <ObjectDisposedException>((Action)(() => { ReadOnlyMemory <byte> roBuffer = buffer.Memory; })); }
public static void MemoryPoolPinBadOffset(int byteOffset) { MemoryPool <int> pool = MemoryPool <int> .Shared; OwnedMemory <int> block = pool.Rent(10); Span <int> sp = block.Span; Assert.Equal(block.Length, sp.Length); Assert.Throws <ArgumentOutOfRangeException>(() => block.Pin(byteOffset: byteOffset)); }
public static void MemoryPoolPin(int byteOffset) { MemoryPool <int> pool = MemoryPool <int> .Shared; using (OwnedMemory <int> block = pool.Rent(10)) { Span <int> sp = block.Span; Assert.Equal(block.Length, sp.Length); using (MemoryHandle newMemoryHandle = block.Pin(byteOffset: byteOffset)) { unsafe { void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp)); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer) - byteOffset); } } } }
public static void MemoryPoolPinBadOffsetTooLarge() { MemoryPool <int> pool = MemoryPool <int> .Shared; OwnedMemory <int> block = pool.Rent(10); Span <int> sp = block.Span; Assert.Equal(block.Length, sp.Length); int byteOffset = 0; try { byteOffset = checked (block.Length * sizeof(int) + 1); } catch (OverflowException) { return; // The pool gave us a very large block - too big to compute the byteOffset needed to carry out this test. Skip. } Assert.Throws <ArgumentOutOfRangeException>(() => block.Pin(byteOffset: byteOffset)); }
public static void EachRentalIsUniqueUntilDisposed() { MemoryPool <int> pool = MemoryPool <int> .Shared; List <OwnedMemory <int> > priorBlocks = new List <OwnedMemory <int> >(); Random r = new Random(42); List <int> testInputs = new List <int>(); for (int i = 0; i < 100; i++) { testInputs.Add((Math.Abs(r.Next() % 1000)) + 1); } foreach (int minBufferSize in testInputs) { OwnedMemory <int> newBlock = pool.Rent(minBufferSize); Assert.True(newBlock.Length >= minBufferSize); foreach (OwnedMemory <int> prior in priorBlocks) { using (MemoryHandle priorMemoryHandle = prior.Pin()) { using (MemoryHandle newMemoryHandle = newBlock.Pin()) { unsafe { Assert.NotEqual((IntPtr)priorMemoryHandle.Pointer, (IntPtr)newMemoryHandle.Pointer); } } } } priorBlocks.Add(newBlock); } foreach (OwnedMemory <int> prior in priorBlocks) { prior.Release(); prior.Dispose(); } }
public override MemoryHandle Pin(int byteOffset = 0) { _pool.CheckDisposed(); return(_ownedMemory.Pin(byteOffset)); }