Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@microsoft.com>2017-09-29 10:48:22 +0300
committerJan Kotas <jkotas@microsoft.com>2017-09-29 17:33:57 +0300
commitd354a5fabb06cfeacb9c4bccc77c67ee15ec144f (patch)
treee5223980e4a35cd1255e8705edfac7476e413677
parent18eab6069612f6664483865d3df8d1b3a565b573 (diff)
Revert a change to thread requests that was reverted in CoreCLR
CoreCLR revert commit: b8dda0cbf7eae770fc685378ad7c542e2468a209 One of the two commits that were reverted in the commit above was merged into this PR. It was causing issues with a missing thread request.
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs82
1 files changed, 19 insertions, 63 deletions
diff --git a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs
index 2c382076c..e1db16f85 100644
--- a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs
@@ -58,12 +58,6 @@ namespace System.Threading
public static WorkStealingQueue[] Queues => _queues;
- // Track whether the WorkStealingQueueList is empty
- // Three states simplifies race conditions. They may be considered.
- // Now Active --> Maybe Inactive -> Confirmed Inactive
- public const int WsqNowActive = 2;
- public static int wsqActive;
-
public static void Add(WorkStealingQueue queue)
{
Debug.Assert(queue != null);
@@ -386,6 +380,7 @@ namespace System.Threading
missedSteal = true;
}
+
return null;
}
}
@@ -451,18 +446,6 @@ namespace System.Threading
if (null != tl)
{
tl.workStealingQueue.LocalPush(callback);
-
- // We must guarantee wsqActive is set to WsqNowActive after we push
- // The ordering must be global because we rely on other threads
- // observing in this order
- Interlocked.MemoryBarrier();
-
- // We do not want to simply write. We want to prevent unnecessary writes
- // which would invalidate reader's caches
- if (WorkStealingQueueList.wsqActive != WorkStealingQueueList.WsqNowActive)
- {
- Volatile.Write(ref WorkStealingQueueList.wsqActive, WorkStealingQueueList.WsqNowActive);
- }
}
else
{
@@ -480,56 +463,33 @@ namespace System.Threading
public IThreadPoolWorkItem Dequeue(ThreadPoolWorkQueueThreadLocals tl, ref bool missedSteal)
{
+ WorkStealingQueue localWsq = tl.workStealingQueue;
IThreadPoolWorkItem callback;
- int wsqActiveObserved = WorkStealingQueueList.wsqActive;
- if (wsqActiveObserved > 0)
- {
- WorkStealingQueue localWsq = tl.workStealingQueue;
- if ((callback = localWsq.LocalPop()) == null && // first try the local queue
- !workItems.TryDequeue(out callback)) // then try the global queue
+ if ((callback = localWsq.LocalPop()) == null && // first try the local queue
+ !workItems.TryDequeue(out callback)) // then try the global queue
+ {
+ // finally try to steal from another thread's local queue
+ WorkStealingQueue[] queues = WorkStealingQueueList.Queues;
+ int c = queues.Length;
+ Debug.Assert(c > 0, "There must at least be a queue for this thread.");
+ int maxIndex = c - 1;
+ int i = tl.random.Next(c);
+ while (c > 0)
{
- // finally try to steal from another thread's local queue
- WorkStealingQueue[] queues = WorkStealingQueueList.Queues;
- int c = queues.Length;
- Debug.Assert(c > 0, "There must at least be a queue for this thread.");
- int maxIndex = c - 1;
- int i = tl.random.Next(c);
- while (c > 0)
+ i = (i < maxIndex) ? i + 1 : 0;
+ WorkStealingQueue otherQueue = queues[i];
+ if (otherQueue != localWsq && otherQueue.CanSteal)
{
- i = (i < maxIndex) ? i + 1 : 0;
- WorkStealingQueue otherQueue = queues[i];
- if (otherQueue != localWsq && otherQueue.CanSteal)
+ callback = otherQueue.TrySteal(ref missedSteal);
+ if (callback != null)
{
- callback = otherQueue.TrySteal(ref missedSteal);
- if (callback != null)
- {
- break;
- }
+ break;
}
- c--;
- }
- if ((callback == null) && !missedSteal)
- {
- // Only decrement if the value is unchanged since we started looking for work
- // This prevents multiple threads decrementing based on overlapping scans.
- //
- // When we decrement from active, the producer may have inserted a queue item during our scan
- // therefore we cannot transition to empty
- //
- // When we decrement from Maybe Inactive, if the producer inserted a queue item during our scan,
- // the producer must write Active. We may transition to empty briefly if we beat the
- // producer's write, but the producer will then overwrite us before waking threads.
- // So effectively we cannot mark the queue empty when an item is in the queue.
- Interlocked.CompareExchange(ref WorkStealingQueueList.wsqActive, wsqActiveObserved - 1, wsqActiveObserved);
}
+ c--;
}
}
- else
- {
- // We only need to look at the global queue since WorkStealingQueueList is inactive
- workItems.TryDequeue(out callback);
- }
return callback;
}
@@ -642,7 +602,6 @@ namespace System.Threading
}
}
-
// Simple random number generator. We don't need great randomness, we just need a little and for it to be fast.
internal struct FastRandom // xorshift prng
{
@@ -668,14 +627,12 @@ namespace System.Threading
}
}
-
// Holds a WorkStealingQueue, and remmoves it from the list when this object is no longer referened.
internal sealed class ThreadPoolWorkQueueThreadLocals
{
[ThreadStatic]
public static ThreadPoolWorkQueueThreadLocals threadLocals;
-
public readonly ThreadPoolWorkQueue workQueue;
public readonly ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue;
public FastRandom random = new FastRandom(Environment.CurrentManagedThreadId); // mutable struct, do not copy or make readonly
@@ -802,7 +759,6 @@ namespace System.Threading
}
}
-
internal sealed class QueueUserWorkItemCallbackDefaultContext : IThreadPoolWorkItem
{
private WaitCallback callback;