Пример #1
0
        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);
        }
Пример #2
0
            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);
            }
Пример #3
0
        // -----------------------------
        // ---- 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;
        }
Пример #4
0
        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]);
        }
Пример #5
0
        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;
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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();
            }
        }
Пример #8
0
        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");
        }
Пример #9
0
            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);
            }
Пример #10
0
        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();
        }
Пример #11
0
        /// <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));
        }
Пример #12
0
        // [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);
        }
Пример #13
0
 /// <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)
 {
 }
Пример #14
0
 /// <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)
 {
 }
Пример #15
0
 /// <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)
 {
 }