using System;using System.Runtime;using System.Collections.Generic;using System.Threading; namespace System.ServiceModel.Channels{ internal class SynchronizedPool<T> where T : class { private struct Entry { public int threadID; public T value; } private struct PendingEntry { public int returnCount; public int threadID; } private static class SynchronizedPoolHelper { public static readonly int ProcessorCount = SynchronizedPool<T>.SynchronizedPoolHelper.GetProcessorCount(); private static int GetProcessorCount() { return Environment.ProcessorCount; } } private class GlobalPool { private Stack<T> items; private int maxCount; public int MaxCount { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.maxCount; } set { lock (this.ThisLock) { while (this.items.Count > value) { this.items.Pop(); } this.maxCount = value; } } } private object ThisLock { get { return this; } } public GlobalPool(int maxCount) { this.items = new Stack<T>(); this.maxCount = maxCount; } public void DecrementMaxCount() { lock (this.ThisLock) { if (this.items.Count == this.maxCount) { this.items.Pop(); } this.maxCount--; } } public T Take() { if (this.items.Count > 0) { lock (this.ThisLock) { if (this.items.Count > 0) { return this.items.Pop(); } } } return default(T); } public bool Return(T value) { if (this.items.Count < this.MaxCount) { lock (this.ThisLock) { if (this.items.Count < this.MaxCount) { this.items.Push(value); return true; } } return false; } return false; } public void Clear() { lock (this.ThisLock) { this.items.Clear(); } } } private SynchronizedPool<T>.Entry[] entries; private SynchronizedPool<T>.GlobalPool globalPool; private int maxCount; private SynchronizedPool<T>.PendingEntry[] pending; private int promotionFailures; private const int maxPendingEntries = 128; private const int maxPromotionFailures = 64; private const int maxReturnsBeforePromotion = 64; private const int maxThreadItemsPerProcessor = 16; private object ThisLock { get { return this; } } public SynchronizedPool(int maxCount) { int num = maxCount; int num2 = 16 + SynchronizedPool<T>.SynchronizedPoolHelper.ProcessorCount; if (num > num2) { num = num2; } this.maxCount = maxCount; this.entries = new SynchronizedPool<T>.Entry[num]; this.pending = new SynchronizedPool<T>.PendingEntry[4]; this.globalPool = new SynchronizedPool<T>.GlobalPool(maxCount); } public void Clear() { SynchronizedPool<T>.Entry[] array = this.entries; for (int i = 0; i < array.Length; i++) { array[i].value = default(T); } this.globalPool.Clear(); } private void HandlePromotionFailure(int thisThreadID) { int num = this.promotionFailures + 1; if (num >= 64) { lock (this.ThisLock) { this.entries = new SynchronizedPool<T>.Entry[this.entries.Length]; this.globalPool.MaxCount = this.maxCount; } this.PromoteThread(thisThreadID); return; } this.promotionFailures = num; } private bool PromoteThread(int thisThreadID) { lock (this.ThisLock) { for (int i = 0; i < this.entries.Length; i++) { int threadID = this.entries[i].threadID; if (threadID == thisThreadID) { bool result = true; return result; } if (threadID == 0) { this.globalPool.DecrementMaxCount(); this.entries[i].threadID = thisThreadID; bool result = true; return result; } } } return false; } private void RecordReturnToGlobalPool(int thisThreadID) { SynchronizedPool<T>.PendingEntry[] array = this.pending; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { int num = array[i].returnCount + 1; if (num < 64) { array[i].returnCount = num; return; } array[i].returnCount = 0; if (!this.PromoteThread(thisThreadID)) { this.HandlePromotionFailure(thisThreadID); return; } break; } else { if (threadID == 0) { return; } i++; } } } private void RecordTakeFromGlobalPool(int thisThreadID) { SynchronizedPool<T>.PendingEntry[] array = this.pending; for (int i = 0; i < array.Length; i++) { int threadID = array[i].threadID; if (threadID == thisThreadID) { return; } if (threadID == 0) { lock (array) { if (array[i].threadID == 0) { array[i].threadID = thisThreadID; return; } } } } if (array.Length >= 128) { this.pending = new SynchronizedPool<T>.PendingEntry[array.Length]; return; } SynchronizedPool<T>.PendingEntry[] destinationArray = new SynchronizedPool<T>.PendingEntry[array.Length * 2]; Array.Copy(array, destinationArray, array.Length); this.pending = destinationArray; } public bool Return(T value) { int managedThreadId = Thread.CurrentThread.ManagedThreadId; return managedThreadId != 0 && (this.ReturnToPerThreadPool(managedThreadId, value) || this.ReturnToGlobalPool(managedThreadId, value)); } private bool ReturnToPerThreadPool(int thisThreadID, T value) { SynchronizedPool<T>.Entry[] array = this.entries; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { if (array[i].value == null) { array[i].value = value; return true; } return false; } else { if (threadID == 0) { break; } i++; } } return false; } private bool ReturnToGlobalPool(int thisThreadID, T value) { this.RecordReturnToGlobalPool(thisThreadID); return this.globalPool.Return(value); } public T Take() { int managedThreadId = Thread.CurrentThread.ManagedThreadId; if (managedThreadId == 0) { return default(T); } T t = this.TakeFromPerThreadPool(managedThreadId); if (t != null) { return t; } return this.TakeFromGlobalPool(managedThreadId); } private T TakeFromPerThreadPool(int thisThreadID) { SynchronizedPool<T>.Entry[] array = this.entries; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { T value = array[i].value; if (value != null) { array[i].value = default(T); return value; } return default(T); } else { if (threadID == 0) { break; } i++; } } return default(T); } private T TakeFromGlobalPool(int thisThreadID) { this.RecordTakeFromGlobalPool(thisThreadID); return this.globalPool.Take(); } } internal abstract class InternalBufferManager { private class PooledBufferManager : InternalBufferManager { private abstract class BufferPool { private class SynchronizedBufferPool : InternalBufferManager.PooledBufferManager.BufferPool { private SynchronizedPool<byte[]> innerPool; internal SynchronizedBufferPool(int bufferSize, int limit) : base(bufferSize, limit) { this.innerPool = new SynchronizedPool<byte[]>(limit); } internal override void OnClear() { this.innerPool.Clear(); } internal override byte[] Take() { return this.innerPool.Take(); } internal override bool Return(byte[] buffer) { return this.innerPool.Return(buffer); } } private class LargeBufferPool : InternalBufferManager.PooledBufferManager.BufferPool { private Stack<byte[]> items; private object ThisLock { get { return this.items; } } internal LargeBufferPool(int bufferSize, int limit) : base(bufferSize, limit) { this.items = new Stack<byte[]>(limit); } internal override void OnClear() { lock (this.ThisLock) { this.items.Clear(); } } internal override byte[] Take() { lock (this.ThisLock) { if (this.items.Count > 0) { return this.items.Pop(); } } return null; } internal override bool Return(byte[] buffer) { lock (this.ThisLock) { if (this.items.Count < base.Limit) { this.items.Push(buffer); return true; } } return false; } } private int bufferSize; private int count; private int limit; private int misses; private int peak; public int BufferSize { get { return this.bufferSize; } } public int Limit { get { return this.limit; } } public int Misses { get { return this.misses; } set { this.misses = value; } } public int Peak { get { return this.peak; } } public BufferPool(int bufferSize, int limit) { this.bufferSize = bufferSize; this.limit = limit; } public void Clear() { this.OnClear(); this.count = 0; } public void DecrementCount() { int num = this.count - 1; if (num >= 0) { this.count = num; } } public void IncrementCount() { int num = this.count + 1; if (num <= this.limit) { this.count = num; if (num > this.peak) { this.peak = num; } } } internal abstract byte[] Take(); internal abstract bool Return(byte[] buffer); internal abstract void OnClear(); internal static InternalBufferManager.PooledBufferManager.BufferPool CreatePool(int bufferSize, int limit) { if (bufferSize < 85000) { return new InternalBufferManager.PooledBufferManager.BufferPool.SynchronizedBufferPool(bufferSize, limit); } return new InternalBufferManager.PooledBufferManager.BufferPool.LargeBufferPool(bufferSize, limit); } } private const int minBufferSize = 128; private const int maxMissesBeforeTuning = 8; private const int initialBufferCount = 1; private readonly object tuningLock; private int[] bufferSizes; private InternalBufferManager.PooledBufferManager.BufferPool[] bufferPools; private long memoryLimit; private long remainingMemory; private bool areQuotasBeingTuned; private int totalMisses; public PooledBufferManager(long maxMemoryToPool, int maxBufferSize) { this.tuningLock = new object(); this.memoryLimit = maxMemoryToPool;Lines 1–500 of 867. Load more
using System; using System.Runtime; using System.Collections.Generic; using System.Threading; namespace System.ServiceModel.Channels { internal class SynchronizedPool<T> where T : class { private struct Entry { public int threadID; public T value; } private struct PendingEntry { public int returnCount; public int threadID; } private static class SynchronizedPoolHelper { public static readonly int ProcessorCount = SynchronizedPool<T>.SynchronizedPoolHelper.GetProcessorCount(); private static int GetProcessorCount() { return Environment.ProcessorCount; } } private class GlobalPool { private Stack<T> items; private int maxCount; public int MaxCount { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.maxCount; } set { lock (this.ThisLock) { while (this.items.Count > value) { this.items.Pop(); } this.maxCount = value; } } } private object ThisLock { get { return this; } } public GlobalPool(int maxCount) { this.items = new Stack<T>(); this.maxCount = maxCount; } public void DecrementMaxCount() { lock (this.ThisLock) { if (this.items.Count == this.maxCount) { this.items.Pop(); } this.maxCount--; } } public T Take() { if (this.items.Count > 0) { lock (this.ThisLock) { if (this.items.Count > 0) { return this.items.Pop(); } } } return default(T); } public bool Return(T value) { if (this.items.Count < this.MaxCount) { lock (this.ThisLock) { if (this.items.Count < this.MaxCount) { this.items.Push(value); return true; } } return false; } return false; } public void Clear() { lock (this.ThisLock) { this.items.Clear(); } } } private SynchronizedPool<T>.Entry[] entries; private SynchronizedPool<T>.GlobalPool globalPool; private int maxCount; private SynchronizedPool<T>.PendingEntry[] pending; private int promotionFailures; private const int maxPendingEntries = 128; private const int maxPromotionFailures = 64; private const int maxReturnsBeforePromotion = 64; private const int maxThreadItemsPerProcessor = 16; private object ThisLock { get { return this; } } public SynchronizedPool(int maxCount) { int num = maxCount; int num2 = 16 + SynchronizedPool<T>.SynchronizedPoolHelper.ProcessorCount; if (num > num2) { num = num2; } this.maxCount = maxCount; this.entries = new SynchronizedPool<T>.Entry[num]; this.pending = new SynchronizedPool<T>.PendingEntry[4]; this.globalPool = new SynchronizedPool<T>.GlobalPool(maxCount); } public void Clear() { SynchronizedPool<T>.Entry[] array = this.entries; for (int i = 0; i < array.Length; i++) { array[i].value = default(T); } this.globalPool.Clear(); } private void HandlePromotionFailure(int thisThreadID) { int num = this.promotionFailures + 1; if (num >= 64) { lock (this.ThisLock) { this.entries = new SynchronizedPool<T>.Entry[this.entries.Length]; this.globalPool.MaxCount = this.maxCount; } this.PromoteThread(thisThreadID); return; } this.promotionFailures = num; } private bool PromoteThread(int thisThreadID) { lock (this.ThisLock) { for (int i = 0; i < this.entries.Length; i++) { int threadID = this.entries[i].threadID; if (threadID == thisThreadID) { bool result = true; return result; } if (threadID == 0) { this.globalPool.DecrementMaxCount(); this.entries[i].threadID = thisThreadID; bool result = true; return result; } } } return false; } private void RecordReturnToGlobalPool(int thisThreadID) { SynchronizedPool<T>.PendingEntry[] array = this.pending; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { int num = array[i].returnCount + 1; if (num < 64) { array[i].returnCount = num; return; } array[i].returnCount = 0; if (!this.PromoteThread(thisThreadID)) { this.HandlePromotionFailure(thisThreadID); return; } break; } else { if (threadID == 0) { return; } i++; } } } private void RecordTakeFromGlobalPool(int thisThreadID) { SynchronizedPool<T>.PendingEntry[] array = this.pending; for (int i = 0; i < array.Length; i++) { int threadID = array[i].threadID; if (threadID == thisThreadID) { return; } if (threadID == 0) { lock (array) { if (array[i].threadID == 0) { array[i].threadID = thisThreadID; return; } } } } if (array.Length >= 128) { this.pending = new SynchronizedPool<T>.PendingEntry[array.Length]; return; } SynchronizedPool<T>.PendingEntry[] destinationArray = new SynchronizedPool<T>.PendingEntry[array.Length * 2]; Array.Copy(array, destinationArray, array.Length); this.pending = destinationArray; } public bool Return(T value) { int managedThreadId = Thread.CurrentThread.ManagedThreadId; return managedThreadId != 0 && (this.ReturnToPerThreadPool(managedThreadId, value) || this.ReturnToGlobalPool(managedThreadId, value)); } private bool ReturnToPerThreadPool(int thisThreadID, T value) { SynchronizedPool<T>.Entry[] array = this.entries; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { if (array[i].value == null) { array[i].value = value; return true; } return false; } else { if (threadID == 0) { break; } i++; } } return false; } private bool ReturnToGlobalPool(int thisThreadID, T value) { this.RecordReturnToGlobalPool(thisThreadID); return this.globalPool.Return(value); } public T Take() { int managedThreadId = Thread.CurrentThread.ManagedThreadId; if (managedThreadId == 0) { return default(T); } T t = this.TakeFromPerThreadPool(managedThreadId); if (t != null) { return t; } return this.TakeFromGlobalPool(managedThreadId); } private T TakeFromPerThreadPool(int thisThreadID) { SynchronizedPool<T>.Entry[] array = this.entries; int i = 0; while (i < array.Length) { int threadID = array[i].threadID; if (threadID == thisThreadID) { T value = array[i].value; if (value != null) { array[i].value = default(T); return value; } return default(T); } else { if (threadID == 0) { break; } i++; } } return default(T); } private T TakeFromGlobalPool(int thisThreadID) { this.RecordTakeFromGlobalPool(thisThreadID); return this.globalPool.Take(); } } internal abstract class InternalBufferManager { private class PooledBufferManager : InternalBufferManager { private abstract class BufferPool { private class SynchronizedBufferPool : InternalBufferManager.PooledBufferManager.BufferPool { private SynchronizedPool<byte[]> innerPool; internal SynchronizedBufferPool(int bufferSize, int limit) : base(bufferSize, limit) { this.innerPool = new SynchronizedPool<byte[]>(limit); } internal override void OnClear() { this.innerPool.Clear(); } internal override byte[] Take() { return this.innerPool.Take(); } internal override bool Return(byte[] buffer) { return this.innerPool.Return(buffer); } } private class LargeBufferPool : InternalBufferManager.PooledBufferManager.BufferPool { private Stack<byte[]> items; private object ThisLock { get { return this.items; } } internal LargeBufferPool(int bufferSize, int limit) : base(bufferSize, limit) { this.items = new Stack<byte[]>(limit); } internal override void OnClear() { lock (this.ThisLock) { this.items.Clear(); } } internal override byte[] Take() { lock (this.ThisLock) { if (this.items.Count > 0) { return this.items.Pop(); } } return null; } internal override bool Return(byte[] buffer) { lock (this.ThisLock) { if (this.items.Count < base.Limit) { this.items.Push(buffer); return true; } } return false; } } private int bufferSize; private int count; private int limit; private int misses; private int peak; public int BufferSize { get { return this.bufferSize; } } public int Limit { get { return this.limit; } } public int Misses { get { return this.misses; } set { this.misses = value; } } public int Peak { get { return this.peak; } } public BufferPool(int bufferSize, int limit) { this.bufferSize = bufferSize; this.limit = limit; } public void Clear() { this.OnClear(); this.count = 0; } public void DecrementCount() { int num = this.count - 1; if (num >= 0) { this.count = num; } } public void IncrementCount() { int num = this.count + 1; if (num <= this.limit) { this.count = num; if (num > this.peak) { this.peak = num; } } } internal abstract byte[] Take(); internal abstract bool Return(byte[] buffer); internal abstract void OnClear(); internal static InternalBufferManager.PooledBufferManager.BufferPool CreatePool(int bufferSize, int limit) { if (bufferSize < 85000) { return new InternalBufferManager.PooledBufferManager.BufferPool.SynchronizedBufferPool(bufferSize, limit); } return new InternalBufferManager.PooledBufferManager.BufferPool.LargeBufferPool(bufferSize, limit); } } private const int minBufferSize = 128; private const int maxMissesBeforeTuning = 8; private const int initialBufferCount = 1; private readonly object tuningLock; private int[] bufferSizes; private InternalBufferManager.PooledBufferManager.BufferPool[] bufferPools; private long memoryLimit; private long remainingMemory; private bool areQuotasBeingTuned; private int totalMisses; public PooledBufferManager(long maxMemoryToPool, int maxBufferSize) { this.tuningLock = new object(); this.memoryLimit = maxMemoryToPool;