From 306a286962330ec034e07483d839f919ced5b0b7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Laval?= Date: Thu, 2 Dec 2010 18:12:51 +0000 Subject: [PATCH] [Task Scheduler] Track re-entrant call to WorkerMethod from normal ThreadWorker and make them use their deque --- .../System.Threading.Tasks/ThreadWorker.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs b/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs index 6397e0dbba4..88703678efb 100644 --- a/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs +++ b/mcs/class/corlib/System.Threading.Tasks/ThreadWorker.cs @@ -32,6 +32,13 @@ namespace System.Threading.Tasks internal class ThreadWorker : IDisposable { Thread workerThread; + + /* This field is used when a TheadWorker have to call Task.Wait + * which bring him back here with the static WorkerMethod although + * it's more optimized for him to continue calling its own WorkerMethod + */ + [ThreadStatic] + static ThreadWorker autoReference; readonly IDequeOperations dDeque; readonly ThreadWorker[] others; @@ -114,6 +121,7 @@ namespace System.Threading.Tasks { int sleepTime = 0; SpinWait wait = new SpinWait (); + autoReference = this; // Main loop while (started == 1) { @@ -202,13 +210,16 @@ namespace System.Threading.Tasks while (!predicate ()) { Task value; - // Dequeue only one item as we have restriction - if (sharedWorkQueue.TryTake (out value)) { - if (value != null) { + // If we are in fact a normal ThreadWorker, use our own deque + if (autoReference != null) { + while (autoReference.dDeque.PopBottom (out value) == PopResult.Succeed && value != null) { if (CheckTaskFitness (value)) - value.Execute (null); + value.Execute (autoReference.ChildWorkAdder); else - sharedWorkQueue.TryAdd (value); + autoReference.dDeque.PushBottom (value); + + if (predicate ()) + return; } } -- 2.25.1