867 lines · 30.5 KB · C#
RawDownload
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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t