Guest User

Untitled

a guest
Jun 29th, 2017
691
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 1.98 KB | None | 0 0
  1. using System;
  2.  
  3. namespace SuperTest
  4. {
  5.     internal class ConcurrentQueue<T>
  6.     {
  7.         private const long Size = 4096;
  8.         private const long MaxSpinOnBusy = 40000000;
  9.         private static readonly long MRingModMask = ClosestExponentOf2() - 1;
  10.         private static readonly long MSize = ClosestExponentOf2();
  11.  
  12.         private static readonly T MEmpty = default(T);
  13.  
  14.         private readonly object _mLock = new object();
  15.  
  16.         private readonly T[] _mMem = new T[MSize];
  17.         private long _mReadPtr;
  18.         private long _mWritePtr;
  19.  
  20.         private static long Log2(int n, int p = 0)
  21.         {
  22.             return n <= 1 ? p : Log2(n / 2, p + 1);
  23.         }
  24.  
  25.         private static int ClosestExponentOf2()
  26.         {
  27.             return (int) 1UL << (int) (Log2((int) (Size - 1)) + 1);
  28.         }
  29.  
  30.         public T Pop()
  31.         {
  32.             if (!Peek())
  33.                 return MEmpty;
  34.  
  35.             lock (_mLock)
  36.             {
  37.                 if (!Peek())
  38.                     return MEmpty;
  39.  
  40.                 var ret = _mMem[_mReadPtr & MRingModMask];
  41.                 _mReadPtr++;
  42.                 return ret;
  43.             }
  44.         }
  45.  
  46.         public bool Peek()
  47.         {
  48.             return _mWritePtr != _mReadPtr;
  49.         }
  50.  
  51.         private long GetCount()
  52.         {
  53.             return _mWritePtr > _mReadPtr ? _mWritePtr - _mReadPtr : _mReadPtr - _mWritePtr;
  54.         }
  55.  
  56.         private bool BusyWaitForPush()
  57.         {
  58.             long start = 0;
  59.             while (GetCount() == MSize)
  60.                 if (start++ > MaxSpinOnBusy)
  61.                     return false;
  62.             return true;
  63.         }
  64.  
  65.         public void Push(T pItem)
  66.         {
  67.             if (!BusyWaitForPush())
  68.                 throw new InvalidOperationException("Concurrent queue full cannot write to it!");
  69.  
  70.             lock (_mLock)
  71.             {
  72.                 _mMem[_mWritePtr & MRingModMask] = pItem;
  73.                 _mWritePtr++;
  74.             }
  75.         }
  76.     }
  77. }
Advertisement
Add Comment
Please, Sign In to add comment