public void RefCountedTest() { var sharedPool = new SharedPool <UnmanagedBuffer>(() => UnmanagedBuffer.Allocate(100), 1); var shared = sharedPool.GetOrCreate(); // refcount = 1 // a private copy shoudl point to the same resource var otherShared = shared.DeepClone(); // refcount = 1 + 1 Assert.AreNotEqual(shared, otherShared); Assert.AreEqual(shared.Inner, otherShared.Inner); Assert.AreEqual(shared.Resource, otherShared.Resource); // a clone should point to the same resource, but should not reuse the container var cloned = otherShared; Serializer.Clone(shared, ref cloned, new SerializationContext()); // refcount = 2 - 1 + 1 Assert.AreNotEqual(shared, cloned); Assert.AreEqual(shared.Inner, cloned.Inner); Assert.AreEqual(shared.Resource, cloned.Resource); // disposing should not affect other copies shared.Dispose(); // refcount = 2 - 1 Assert.AreEqual(0, sharedPool.AvailableCount); Assert.IsNull(shared.Inner); Assert.IsNull(shared.Resource); Assert.IsNotNull(cloned.Inner); Assert.IsNotNull(cloned.Resource); // disposing the last copy should return the resource to the pool cloned.Dispose(); // refcount = 1 - 1 Assert.AreEqual(1, sharedPool.AvailableCount); Assert.IsNull(cloned.Inner); Assert.IsNull(cloned.Resource); }
static void RunTest(string testTypeName, string throwExceptionStr) { bool throwExceptionInner = bool.Parse(throwExceptionStr); var buffer = UnmanagedBuffer <L8> .Allocate(100); var allocator = new MockUnmanagedMemoryAllocator <L8>(buffer); Configuration.Default.MemoryAllocator = allocator; var image = new Image <L8>(10, 10); Assert.Equal(1, UnmanagedMemoryHandle.TotalOutstandingHandles); try { GetTest(testTypeName).ProcessPixelRowsImpl(image, _ => { ((IDisposable)buffer).Dispose(); Assert.Equal(1, UnmanagedMemoryHandle.TotalOutstandingHandles); if (throwExceptionInner) { throw new NonFatalException(); } }); } catch (NonFatalException) { } Assert.Equal(0, UnmanagedMemoryHandle.TotalOutstandingHandles); }
// ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- private void EnsureCapacity(int capacity) { // Make sure the requested capacity doesn't exceed SecureString's defined limit if (capacity > MaxLength) { throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity); } // If we already have enough space allocated, we're done if (_buffer != null && (capacity * sizeof(char)) <= (int)_buffer.ByteLength) { return; } // We need more space, so allocate a new buffer, copy all our data into it, // and then swap the new for the old. UnmanagedBuffer newBuffer = UnmanagedBuffer.Allocate(capacity * sizeof(char)); if (_buffer != null) { UnmanagedBuffer.Copy(_buffer, newBuffer, _buffer.ByteLength); _buffer.Dispose(); } _buffer = newBuffer; }
public void Allocate_CreatesValidBuffer() { using var buffer = UnmanagedBuffer <int> .Allocate(10); Span <int> span = buffer.GetSpan(); Assert.Equal(10, span.Length); span[9] = 123; Assert.Equal(123, span[9]); }
private SecureString(SecureString str) { Debug.Assert(str._buffer != null, "Expected other SecureString's buffer to be non-null"); Debug.Assert(str._encrypted, "Expected to be used only on encrypted SecureStrings"); _buffer = UnmanagedBuffer.Allocate((int)str._buffer.ByteLength); Debug.Assert(_buffer != null); UnmanagedBuffer.Copy(str._buffer, _buffer, str._buffer.ByteLength); _decryptedLength = str._decryptedLength; _encrypted = str._encrypted; }
public void DoubleDispose() { var sharedPool = new SharedPool <UnmanagedBuffer>(() => UnmanagedBuffer.Allocate(100), 1); var shared = sharedPool.GetOrCreate(); shared.Dispose(); try { shared.Dispose(); Assert.Fail("Expected an exception from the second Dispose call"); } catch (Exception e) { Assert.IsTrue(e is ObjectDisposedException); } }
private void Initialize(ReadOnlySpan <char> value) { _buffer = UnmanagedBuffer.Allocate(GetAlignedByteSize(value.Length)); _decryptedLength = value.Length; SafeBuffer?bufferToRelease = null; try { Span <char> span = AcquireSpan(ref bufferToRelease); value.CopyTo(span); } finally { ProtectMemory(); bufferToRelease?.DangerousRelease(); } }
public void RecyclerPerf() { var sharedPool = new SharedPool <UnmanagedBuffer>(() => UnmanagedBuffer.Allocate(100), 1); var shared = sharedPool.GetOrCreate(); shared.Dispose(); Stopwatch sw = Stopwatch.StartNew(); int iterations = 10; for (int i = 0; i < iterations; i++) { sharedPool.TryGet(out shared); shared.Dispose(); } sw.Stop(); Console.WriteLine($"Get + Release = {sw.ElapsedMilliseconds * 1000000d / iterations} ns"); }
static void RunTest() { var buffer = UnmanagedBuffer <int> .Allocate(10); Assert.Equal(1, UnmanagedMemoryHandle.TotalOutstandingHandles); Span <int> span = buffer.GetSpan(); // Pin should AddRef using (MemoryHandle h = buffer.Pin()) { int *ptr = (int *)h.Pointer; ((IDisposable)buffer).Dispose(); Assert.Equal(1, UnmanagedMemoryHandle.TotalOutstandingHandles); ptr[3] = 13; Assert.Equal(13, span[3]); } // Unpin should ReleaseRef Assert.Equal(0, UnmanagedMemoryHandle.TotalOutstandingHandles); }
private void EnsureCapacity(int capacity) { if (capacity > MaxLength) { throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity); } Debug.Assert(_buffer != null); if ((uint)capacity * sizeof(char) <= _buffer.ByteLength) { return; } UnmanagedBuffer oldBuffer = _buffer; UnmanagedBuffer newBuffer = UnmanagedBuffer.Allocate(GetAlignedByteSize(capacity)); UnmanagedBuffer.Copy(oldBuffer, newBuffer, (uint)_decryptedLength * sizeof(char)); _buffer = newBuffer; oldBuffer.Dispose(); }
/// <summary> /// Allocate new image in unmanaged memory. /// </summary> /// <param name="width">Image width.</param> /// <param name="height">Image height.</param> /// <param name="pixelFormat">Image pixel format.</param> /// <returns>Return image allocated in unmanaged memory.</returns> /// <remarks><para>Allocate new image with specified attributes in unmanaged memory.</para> /// </remarks> public static Image Create(int width, int height, PixelFormat pixelFormat) { int bytesPerPixel = pixelFormat.GetBitsPerPixel() / 8; // check image size if ((width <= 0) || (height <= 0)) { throw new Exception("Invalid image size specified."); } // calculate stride int stride = width * bytesPerPixel; if (stride % 4 != 0) { stride += 4 - (stride % 4); } // allocate memory for the image return(new Image(UnmanagedBuffer.Allocate(stride * height), width, height, stride, pixelFormat)); }
// [TestMethod, Timeout(60000)] public void RefCountedFinalizationTest() { var sharedPool = new SharedPool <UnmanagedBuffer>(() => UnmanagedBuffer.Allocate(100), 1); var shared = sharedPool.GetOrCreate(); var otherShared = shared.DeepClone(); shared = null; // after GC and finalization, the live copy is not affected GC.Collect(); GC.WaitForPendingFinalizers(); Assert.AreNotEqual(IntPtr.Zero, otherShared.Resource.Data); otherShared = null; // after GC and finalization of all live copies, the resource goes back to the pool without being finalized itself GC.Collect(); GC.WaitForPendingFinalizers(); var wasRecycled = sharedPool.TryGet(out shared); Assert.IsTrue(wasRecycled); Assert.IsNotNull(shared.Resource); Assert.AreNotEqual(IntPtr.Zero, shared.Resource.Data); }
/// <summary> /// Initializes a new instance of the <see cref="Image"/> class. /// </summary> /// <param name="width">Width of image in pixels.</param> /// <param name="height">Height of image in pixels.</param> /// <param name="pixelFormat">Pixel format.</param> public Image(int width, int height, PixelFormat pixelFormat) : this(UnmanagedBuffer.Allocate(height * width * GetBytesPerPixel(pixelFormat)), width, height, width *GetBytesPerPixel(pixelFormat), pixelFormat) { }
/// <summary> /// Initializes a new instance of the <see cref="Image"/> class. /// </summary> /// <param name="width">Image width in pixels.</param> /// <param name="height">Image height in pixels.</param> /// <param name="stride">Image stride (line size in bytes).</param> /// <param name="pixelFormat">Image pixel format.</param> /// <remarks><para><note>Using this constructor, make sure all specified image attributes are correct /// and correspond to unmanaged memory buffer. If some attributes are specified incorrectly, /// this may lead to exceptions working with the unmanaged memory.</note></para></remarks> public Image(int width, int height, int stride, PixelFormat pixelFormat) : this(UnmanagedBuffer.Allocate(height * stride), width, height, stride, pixelFormat) { }
/// <summary> /// Initializes a new instance of the <see cref="ImageBase"/> class. /// </summary> /// <param name="width">Width of image in pixels.</param> /// <param name="height">Height of image in pixels.</param> /// <param name="pixelFormat">Pixel format.</param> public ImageBase(int width, int height, PixelFormat pixelFormat) : this(UnmanagedBuffer.Allocate(height * 4 * ((width * pixelFormat.GetBytesPerPixel() + 3) / 4)), width, height, 4 * ((width * pixelFormat.GetBytesPerPixel() + 3) / 4), pixelFormat) { }