public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal) { callback = (IThreadPoolWorkItem)null; missedSteal = false; ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue1 = tl.workStealingQueue; workStealingQueue1.LocalPop(out callback); if (callback == null) { for (ThreadPoolWorkQueue.QueueSegment comparand = this.queueTail; !comparand.TryDequeue(out callback) && comparand.Next != null && comparand.IsUsedUp(); comparand = this.queueTail) { Interlocked.CompareExchange <ThreadPoolWorkQueue.QueueSegment>(ref this.queueTail, comparand.Next, comparand); } } if (callback != null) { return; } ThreadPoolWorkQueue.WorkStealingQueue[] current = ThreadPoolWorkQueue.allThreadQueues.Current; int num = tl.random.Next(current.Length); for (int length = current.Length; length > 0; --length) { ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue2 = Volatile.Read <ThreadPoolWorkQueue.WorkStealingQueue>(ref current[num % current.Length]); if (workStealingQueue2 != null && workStealingQueue2 != workStealingQueue1 && workStealingQueue2.TrySteal(out callback, ref missedSteal)) { break; } ++num; } }
public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal) { callback = null; missedSteal = false; ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue = tl.workStealingQueue; workStealingQueue.LocalPop(out callback); if (callback == null) { ThreadPoolWorkQueue.QueueSegment queueSegment = this.queueTail; while (!queueSegment.TryDequeue(out callback) && queueSegment.Next != null && queueSegment.IsUsedUp()) { Interlocked.CompareExchange <ThreadPoolWorkQueue.QueueSegment>(ref this.queueTail, queueSegment.Next, queueSegment); queueSegment = this.queueTail; } } if (callback == null) { ThreadPoolWorkQueue.WorkStealingQueue[] array = ThreadPoolWorkQueue.allThreadQueues.Current; int num = tl.random.Next(array.Length); for (int i = array.Length; i > 0; i--) { ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue2 = Volatile.Read <ThreadPoolWorkQueue.WorkStealingQueue>(ref array[num % array.Length]); if (workStealingQueue2 != null && workStealingQueue2 != workStealingQueue && workStealingQueue2.TrySteal(out callback, ref missedSteal)) { break; } num++; } } }