public EncryptionBuffersPool(bool registerLowMemory = true, bool registerCleanup = true) { _maxNumberOfAllocationsToKeepInGlobalStackPerSlot = PlatformDetails.Is32Bits == false ? 128 : 32; var numberOfSlots = Bits.MostSignificantBit(MaxNumberOfPagesToCache * Constants.Storage.PageSize) + 1; _items = new PerCoreContainer <NativeAllocation> [numberOfSlots]; _globalStacks = new CountingConcurrentStack <NativeAllocation> [numberOfSlots]; _lastPerCoreCleanups = new DateTime[numberOfSlots]; _lastGlobalStackRebuilds = new DateTime[numberOfSlots]; _numberOfAllocationsDisposedInGlobalStacks = new long[numberOfSlots]; var now = DateTime.UtcNow; for (int i = 0; i < _items.Length; i++) { _items[i] = new PerCoreContainer <NativeAllocation>(); _globalStacks[i] = new CountingConcurrentStack <NativeAllocation>(); _lastPerCoreCleanups[i] = now; _lastGlobalStackRebuilds[i] = now; } if (registerLowMemory) { LowMemoryNotification.Instance.RegisterLowMemoryHandler(this); } if (registerCleanup) { _cleanupTimer = new Timer(Cleanup, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); } }
static void ClearStack(CountingConcurrentStack <NativeAllocation> stack) { if (stack == null || stack.IsEmpty) { return; } while (stack.TryPop(out var allocation)) { if (allocation.InUse.Raise()) { allocation.Dispose(); } } }
static bool TryGetFromStack(CountingConcurrentStack<T> stack, out T context) { context = default; if (stack == null || stack.IsEmpty) return false; while (stack.TryPop(out context)) { if (context.InUse.Raise() == false) continue; context.Renew(); return true; } return false; }