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); } }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }