Пример #1
0
        private void TxOnDispose(IPagerLevelTransactionState tx)
        {
            if (tx.CryptoPagerTransactionState == null)
            {
                return;
            }

            if (tx.CryptoPagerTransactionState.TryGetValue(this, out var state) == false)
            {
                return;
            }

            tx.CryptoPagerTransactionState.Remove(this);

            foreach (var buffer in state.LoadedBuffers)
            {
                if (buffer.Value.OriginalSize != null && buffer.Value.OriginalSize == 0)
                {
                    // Pages that are marked with OriginalSize = 0 were separated from a larger allocation, we cannot free them directly.
                    // The first page of the section will be returned and when it will be freed, all the other parts will be freed as well.
                    // We still need to return the buffer allocated for the hash
                    _encryptionBuffersPool.Return(buffer.Value.Hash, EncryptionBuffer.HashSizeInt, buffer.Value.AllocatingThread);

                    continue;
                }

                ReturnBuffer(buffer.Value);
            }
        }
Пример #2
0
        private void TxOnDispose(IPagerLevelTransactionState tx)
        {
            if (tx.CryptoPagerTransactionState == null)
            {
                return;
            }

            if (tx.CryptoPagerTransactionState.TryGetValue(this, out var state) == false)
            {
                return;
            }

            tx.CryptoPagerTransactionState.Remove(this);

            foreach (var buffer in state.LoadedBuffers)
            {
                if (buffer.Value.OriginalSize != null && buffer.Value.OriginalSize == 0)
                {
                    // Pages that are marked with OriginalSize = 0 were seperated from a larger allocation, we cannot free them directly.
                    // The first page of the section will be returned and when it will be freed, all the other parts will be freed as well.
                    continue;
                }

                if (buffer.Value.OriginalSize != null && buffer.Value.OriginalSize != 0)
                {
                    // First page of a seperated section, returned with its original size.
                    _encryptionBuffersPool.Return(buffer.Value.Pointer, (int)buffer.Value.OriginalSize, buffer.Value.AllocatingThread);
                    continue;
                }

                // Normal buffers
                _encryptionBuffersPool.Return(buffer.Value.Pointer, buffer.Value.Size, buffer.Value.AllocatingThread);
            }
        }
Пример #3
0
        public void clear_all_buffers_from_current_generation_on_low_memory(LowMemorySeverity lowMemorySeverity)
        {
            var encryptionBuffersPool = new EncryptionBuffersPool();
            var generation            = encryptionBuffersPool.Generation;
            var i      = 1;
            var toFree = new List <(IntPtr, long)>();

            while (i <= new Size(8, SizeUnit.Megabytes).GetValue(SizeUnit.Bytes))
            {
                var ptr = encryptionBuffersPool.Get(i, out _);
                toFree.Add(((IntPtr)ptr, i));

                i *= 2;
            }

            var stats = encryptionBuffersPool.GetStats();

            Assert.Equal(0, stats.TotalSize);

            encryptionBuffersPool.LowMemory(lowMemorySeverity);
            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(0, stats.TotalSize);

            foreach (var o in toFree)
            {
                encryptionBuffersPool.Return((byte *)o.Item1, o.Item2, NativeMemory.ThreadAllocations.Value, generation);
            }

            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(0, stats.TotalSize);

            var size    = 8 * 1024;
            var pointer = encryptionBuffersPool.Get(size, out _);

            encryptionBuffersPool.Return(pointer, size, NativeMemory.ThreadAllocations.Value, encryptionBuffersPool.Generation);

            // will cache the buffer
            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(size, stats.TotalSize);

            // will continue to cache the buffer
            encryptionBuffersPool.LowMemory(lowMemorySeverity);
            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(size, stats.TotalSize);

            encryptionBuffersPool.LowMemoryOver();
            ClearMemory(encryptionBuffersPool);
        }
Пример #4
0
        public void clear_all_buffers_on_extremely_low_memory()
        {
            var encryptionBuffersPool = new EncryptionBuffersPool();
            var generation            = encryptionBuffersPool.Generation;
            var i      = 1;
            var toFree = new List <(IntPtr, long)>();

            while (i <= new Size(8, SizeUnit.Megabytes).GetValue(SizeUnit.Bytes))
            {
                var ptr = encryptionBuffersPool.Get(i, out _);
                toFree.Add(((IntPtr)ptr, i));

                i *= 2;
            }

            var stats = encryptionBuffersPool.GetStats();

            Assert.Equal(0, stats.TotalSize);

            foreach (var o in toFree)
            {
                encryptionBuffersPool.Return((byte *)o.Item1, o.Item2, NativeMemory.ThreadAllocations.Value, generation);
            }

            stats = encryptionBuffersPool.GetStats();
            var allocated = toFree.Sum(x => x.Item2);

            Assert.Equal(allocated, stats.TotalSize);

            ClearMemory(encryptionBuffersPool);
        }
Пример #5
0
        public void properly_calculate_thread_total_allocations_when_we_cant_put_buffer_in_pool()
        {
            var encryptionBuffersPool = new EncryptionBuffersPool(registerLowMemory: false, registerCleanup: false);

            var ptr = encryptionBuffersPool.Get(1, out var initialSize, out var threadStats);

            var size = initialSize;
            var free4KbAlignedMemoryCount       = 0;
            var updateMemoryStatsForThreadCount = 0;
            var testingStuff = encryptionBuffersPool.ForTestingPurposesOnly();

            testingStuff.CanAddToPerCorePool    = false;
            testingStuff.CanAddToGlobalPool     = false;
            testingStuff.OnFree4KbAlignedMemory = s =>
            {
                free4KbAlignedMemoryCount++;
                size -= s;
            };
            testingStuff.OnUpdateMemoryStatsForThread = s =>
            {
                updateMemoryStatsForThreadCount++;
            };

            encryptionBuffersPool.Return(ptr, initialSize, threadStats, encryptionBuffersPool.Generation);

            Assert.Equal(1, free4KbAlignedMemoryCount);
            Assert.Equal(0, size);
            Assert.Equal(0, updateMemoryStatsForThreadCount);
        }
Пример #6
0
        public void clear_buffers_only_when_in_extremely_low_memory()
        {
            var encryptionBuffersPool = new EncryptionBuffersPool();

            var ptr   = encryptionBuffersPool.Get(1, out _);
            var stats = encryptionBuffersPool.GetStats();

            Assert.Equal(0, stats.TotalSize);

            encryptionBuffersPool.Return(ptr, 1, NativeMemory.ThreadAllocations.Value, encryptionBuffersPool.Generation);
            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(1, stats.TotalSize);

            encryptionBuffersPool.LowMemory(LowMemorySeverity.Low);
            stats = encryptionBuffersPool.GetStats();
            Assert.Equal(1, stats.TotalSize);

            ClearMemory(encryptionBuffersPool);
        }
Пример #7
0
        public void dont_pool_buffers_larger_than_8Mb()
        {
            var encryptionBuffersPool = new EncryptionBuffersPool();
            var i      = 1;
            var toFree = new List <(IntPtr, long)>();

            while (i < new Size(64, SizeUnit.Megabytes).GetDoubleValue(SizeUnit.Bytes))
            {
                var ptr = encryptionBuffersPool.Get(i, out _);
                toFree.Add(((IntPtr)ptr, i));

                i *= 2;
            }

            var maxSize   = new Size(8, SizeUnit.Megabytes).GetValue(SizeUnit.Bytes);
            var totalSize = 0L;

            foreach (var o in toFree)
            {
                if (o.Item2 <= maxSize)
                {
                    totalSize += o.Item2;
                }

                encryptionBuffersPool.Return((byte *)o.Item1, o.Item2, NativeMemory.ThreadAllocations.Value, encryptionBuffersPool.Generation);
            }

            var stats = encryptionBuffersPool.GetStats();

            Assert.Equal(totalSize, stats.TotalSize);

            i = 1;
            foreach (var allocationInfo in stats.Details)
            {
                Assert.Equal(1, allocationInfo.NumberOfItems);
                Assert.Equal(i, allocationInfo.AllocationSize);
                i *= 2;
            }

            ClearMemory(encryptionBuffersPool);
        }
Пример #8
0
        public void can_save_buffers_after_low_memory()
        {
            var encryptionBuffersPool = new EncryptionBuffersPool();

            encryptionBuffersPool.LowMemory(LowMemorySeverity.ExtremelyLow);
            encryptionBuffersPool.LowMemoryOver();

            var i      = 1;
            var toFree = new List <(IntPtr, long)>();

            var generation = encryptionBuffersPool.Generation;

            while (i <= 1024)
            {
                var ptr = encryptionBuffersPool.Get(i, out var size, out _);
                toFree.Add(((IntPtr)ptr, i));

                i *= 2;
            }

            var stats = encryptionBuffersPool.GetStats();

            Assert.Equal(0, stats.TotalPoolSize);

            foreach (var o in toFree)
            {
                encryptionBuffersPool.Return((byte *)o.Item1, o.Item2, NativeMemory.ThreadAllocations.Value, generation);
            }

            stats = encryptionBuffersPool.GetStats();
            var allocated = toFree.Sum(x => x.Item2);

            Assert.Equal(allocated, stats.TotalPoolSize);

            ClearMemory(encryptionBuffersPool);
        }