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; } }
private void CleanUp() { if (null != workStealingQueue) { if (null != workQueue) { bool done = false; while (!done) { // Ensure that we won't be aborted between LocalPop and Enqueue. try { } finally { IThreadPoolWorkItem cb = null; if (workStealingQueue.LocalPop(out cb)) { Contract.Assert(null != cb); workQueue.Enqueue(cb, true); } else { done = true; } } } } ThreadPoolWorkQueue.allThreadQueues.Remove(workStealingQueue); } }
private void CleanUp() { if (null != workStealingQueue) { if (null != workQueue) { bool done = false; while (!done) { IThreadPoolWorkItem cb = null; if (workStealingQueue.LocalPop(out cb)) { Debug.Assert(null != cb); workQueue.Enqueue(cb, true); } else { done = true; } } } ThreadPoolWorkQueue.allThreadQueues.Remove(workStealingQueue); } }
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++; } } }
private void CleanUp() { if (null != workStealingQueue) { if (null != workQueue) { IThreadPoolWorkItem cb; while ((cb = workStealingQueue.LocalPop()) != null) { Debug.Assert(null != cb); workQueue.Enqueue(cb, forceGlobal: true); } } ThreadPoolWorkQueue.WorkStealingQueueList.Remove(workStealingQueue); } }