diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs index 0a9892a8be63..d1e9a4580033 100644 --- a/src/mscorlib/src/System/Threading/ThreadPool.cs +++ b/src/mscorlib/src/System/Threading/ThreadPool.cs @@ -148,17 +148,16 @@ internal int Add(T e) } return i; } - else if (i == array.Length - 1) - { - var newSnapshot = new Snapshot(array.Length * 2, array.Length + 1); - T[] newArray = newSnapshot.Data; - - Array.Copy(array, newArray, i + 1); - newArray[i + 1] = e; - m_current = newSnapshot; - return i + 1; - } } + + var oldLength = array.Length; + var newSnapshot = new Snapshot(oldLength * 2, oldLength + 1); + T[] newArray = newSnapshot.Data; + + Array.Copy(array, newArray, oldLength); + newArray[oldLength + 1] = e; + m_current = newSnapshot; + return oldLength + 1; } } } @@ -829,14 +828,17 @@ private static void DequeueStealWithQueue(WorkStealingQueue wsq, int index, ref var otherQueues = allThreadQueues.Current; var total = otherQueues.ActiveLength; var data = otherQueues.Data; + Contract.Assert(data.Length >= total); + var remaining = total; - index = index % total; + // Only positive indices + index = (index & 0x7fff) % total; while (remaining > 0) { remaining--; WorkStealingQueue otherQueue = Volatile.Read(ref data[index]); - index = index + 1 == total ? 0 : index + 1; + index = (index + 1 >= total) ? 0 : index + 1; if (otherQueue != null && otherQueue != wsq && otherQueue.TrySteal(ref callback, ref missedSteal)) @@ -857,14 +859,17 @@ private static void DequeueSteal(int index, ref IThreadPoolWorkItem callback, re // No local queue, may not be other queues if (total == 0) return; var data = otherQueues.Data; + Contract.Assert(data.Length >= total); + var remaining = total; - index = index % total; + // Only positive indices + index = (index & 0x7fff) % total; while (remaining > 0) { remaining--; WorkStealingQueue otherQueue = Volatile.Read(ref data[index]); - index = index + 1 == total ? 0 : index + 1; + index = (index + 1 == total) ? 0 : index + 1; if (otherQueue != null && otherQueue.TrySteal(ref callback, ref missedSteal)) {