public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal) { callback = null; missedSteal = false; WorkStealingQueue wsq = tl.workStealingQueue; if (wsq.LocalPop(out callback)) { Debug.Assert(null != callback); } if (null == callback) { QueueSegment tail = queueTail; while (true) { if (tail.TryDequeue(out callback)) { Debug.Assert(null != callback); break; } if (null == tail.Next || !tail.IsUsedUp()) { break; } else { Interlocked.CompareExchange(ref queueTail, tail.Next, tail); tail = queueTail; } } } if (null == callback) { WorkStealingQueue[] otherQueues = allThreadQueues.Current; int i = tl.random.Next(otherQueues.Length); int c = otherQueues.Length; while (c > 0) { WorkStealingQueue otherQueue = Volatile.Read(ref otherQueues[i % otherQueues.Length]); if (otherQueue != null && otherQueue != wsq && otherQueue.TrySteal(out callback, ref missedSteal)) { Debug.Assert(null != callback); break; } i++; c--; } } }
public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal) { callback = null; missedSteal = false; WorkStealingQueue workStealingQueue = tl.workStealingQueue; workStealingQueue.LocalPop(out callback); if (callback == null) { for (QueueSegment segment = this.queueTail; (!segment.TryDequeue(out callback) && (segment.Next != null)) && segment.IsUsedUp(); segment = this.queueTail) { Interlocked.CompareExchange <QueueSegment>(ref this.queueTail, segment.Next, segment); } } if (callback == null) { WorkStealingQueue[] current = allThreadQueues.Current; int num = tl.random.Next(current.Length); for (int i = current.Length; i > 0; i--) { WorkStealingQueue queue2 = current[num % current.Length]; if (((queue2 != null) && (queue2 != workStealingQueue)) && queue2.TrySteal(out callback, ref missedSteal)) { return; } num++; } } }