2010-04-15 Jérémie Laval <jeremie.laval@gmail.com>
authorJérémie Laval <jeremie.laval@gmail.com>
Thu, 15 Apr 2010 19:01:26 +0000 (19:01 -0000)
committerJérémie Laval <jeremie.laval@gmail.com>
Thu, 15 Apr 2010 19:01:26 +0000 (19:01 -0000)
In class/System/System.Collections.Concurrent/:
   * BlockingCollection.cs:
   * ConcurrentBag.cs: Add BOOTSTRAP_NET_4_0

In class/System/System.Threading/:
   * Barrier.cs: Add BOOTSTRAP_NET_4_0

In class/corlib/System.Collections.Concurrent/:
   * ConcurrentDictionary.cs:
   * ConcurrentSkipList.cs:
   * OrderablePartitioner.cs:
   * Partitioner.cs: Add BOOTSTRAP_NET_4_0 define

In class/corlib/System.Collections/:
   * IStructuralComparable.cs:
   * IStructuralEquatable.cs: Add BOOTSTRAP_NET_4_0 define

In class/corlib/System.Threading.Tasks/:
   * Future.cs:
   * Task.cs:
   * TaskCanceledException.cs:
   * TaskContinuationOptions.cs:
   * TaskCreationOptions.cs:
   * TaskFactory.cs:
   * TaskScheduler.cs:
   * TaskStatus.cs: Add BOOTSTRAP_NET_4_0 define

In class/corlib/System.Threading/:
   * AtomicBoolean.cs:
   * CountdownEvent.cs:
   * SpinLock.cs: Add BOOTSTRAP_NET_4_0 define

In class/corlib/System/:
   * Tuple.cs:
   * Tuples.cs: Add BOOTSTRAP_NET_4_0 define

svn path=/trunk/mcs/; revision=155531

36 files changed:
mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs
mcs/class/System/System.Collections.Concurrent/ChangeLog
mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs
mcs/class/System/System.Threading/Barrier.cs
mcs/class/System/System.Threading/ChangeLog
mcs/class/corlib/System.Collections.Concurrent/ChangeLog
mcs/class/corlib/System.Collections.Concurrent/ConcurrentDictionary.cs
mcs/class/corlib/System.Collections.Concurrent/ConcurrentSkipList.cs
mcs/class/corlib/System.Collections.Concurrent/OrderablePartitioner.cs
mcs/class/corlib/System.Collections.Concurrent/Partitioner.cs
mcs/class/corlib/System.Collections.Concurrent/Partitioners/EnumerablePartitioner.cs
mcs/class/corlib/System.Collections.Concurrent/Partitioners/ListPartitioner.cs
mcs/class/corlib/System.Collections/ChangeLog
mcs/class/corlib/System.Collections/IStructuralComparable.cs
mcs/class/corlib/System.Collections/IStructuralEquatable.cs
mcs/class/corlib/System.Threading.Tasks/ChangeLog
mcs/class/corlib/System.Threading.Tasks/Future.cs
mcs/class/corlib/System.Threading.Tasks/Internal/CyclicDeque.cs
mcs/class/corlib/System.Threading.Tasks/Internal/IScheduler.cs
mcs/class/corlib/System.Threading.Tasks/Internal/Scheduler.cs
mcs/class/corlib/System.Threading.Tasks/Internal/SchedulerProxy.cs
mcs/class/corlib/System.Threading.Tasks/Internal/ThreadWorker.cs
mcs/class/corlib/System.Threading.Tasks/Task.cs
mcs/class/corlib/System.Threading.Tasks/TaskCanceledException.cs
mcs/class/corlib/System.Threading.Tasks/TaskContinuationOptions.cs
mcs/class/corlib/System.Threading.Tasks/TaskCreationOptions.cs
mcs/class/corlib/System.Threading.Tasks/TaskFactory.cs
mcs/class/corlib/System.Threading.Tasks/TaskScheduler.cs
mcs/class/corlib/System.Threading.Tasks/TaskStatus.cs
mcs/class/corlib/System.Threading/AtomicBoolean.cs
mcs/class/corlib/System.Threading/ChangeLog
mcs/class/corlib/System.Threading/CountdownEvent.cs
mcs/class/corlib/System.Threading/SpinLock.cs
mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/Tuple.cs
mcs/class/corlib/System/Tuples.cs

index 53388ae0a67aa558abc132e4bd9dc8ba90ad202b..741e092539ceb0e6454c9712ea4a7b0b84d51701 100644 (file)
@@ -23,7 +23,7 @@
 //
 //
 
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System;
 using System.Threading;
@@ -41,31 +41,29 @@ namespace System.Collections.Concurrent
        {
                readonly IProducerConsumerCollection<T> underlyingColl;
                readonly int upperBound;
-               
-               readonly SpinWait sw = new SpinWait ();
-               
+
                AtomicBoolean isComplete;
                long completeId;
 
                long addId = long.MinValue;
                long removeId = long.MinValue;
-               
+
                #region ctors
                public BlockingCollection ()
                        : this (new ConcurrentQueue<T> (), -1)
                {
                }
-               
+
                public BlockingCollection (int upperBound)
                        : this (new ConcurrentQueue<T> (), upperBound)
                {
                }
-               
+
                public BlockingCollection (IProducerConsumerCollection<T> underlyingColl)
                        : this (underlyingColl, -1)
                {
                }
-               
+
                public BlockingCollection (IProducerConsumerCollection<T> underlyingColl, int upperBound)
                {
                        this.underlyingColl = underlyingColl;
@@ -73,196 +71,196 @@ namespace System.Collections.Concurrent
                        this.isComplete     = new AtomicBoolean ();
                }
                #endregion
-               
+
                #region Add & Remove (+ Try)
                public void Add (T item)
                {
                        Add (item, null);
                }
-               
+
                public void Add (T item, CancellationToken token)
                {
                        Add (item, () => token.IsCancellationRequested);
                }
-               
+
                void Add (T item, Func<bool> cancellationFunc)
                {
                        while (true) {
                                long cachedAddId = addId;
                                long cachedRemoveId = removeId;
-                               
+
                                if (upperBound != -1) {
                                        if (cachedAddId - cachedRemoveId > upperBound) {
                                                Block ();
                                                continue;
                                        }
                                }
-                               
+
                                // Check our transaction id against completed stored one
                                if (isComplete.Value && cachedAddId >= completeId)
                                        throw new InvalidOperationException ("The BlockingCollection<T> has"
                                                                             + " been marked as complete with regards to additions.");
-                               
+
                                if (Interlocked.CompareExchange (ref addId, cachedAddId + 1, cachedAddId) == cachedAddId)
                                        break;
-                               
+
                                if (cancellationFunc != null && cancellationFunc ())
                                        throw new OperationCanceledException ("CancellationToken triggered");
                        }
-                       
-                       
+
+
                        if (!underlyingColl.TryAdd (item))
                                throw new InvalidOperationException ("The underlying collection didn't accept the item.");
                }
-               
+
                public T Take ()
                {
                        return Take (null);
                }
-               
+
                public T Take (CancellationToken token)
                {
                        return Take (() => token.IsCancellationRequested);
                }
-               
+
                T Take (Func<bool> cancellationFunc)
                {
                        while (true) {
                                long cachedRemoveId = removeId;
                                long cachedAddId = addId;
-                               
+
                                // Empty case
                                if (cachedRemoveId == cachedAddId) {
-                                       if (isComplete.Value && cachedRemoveId >= completeId)
+                                       if (IsCompleted)
                                                throw new OperationCanceledException ("The BlockingCollection<T> has"
                                                                                      + " been marked as complete with regards to additions.");
-                                       
+
                                        Block ();
                                        continue;
                                }
-                               
+
                                if (Interlocked.CompareExchange (ref removeId, cachedRemoveId + 1, cachedRemoveId) == cachedRemoveId)
                                        break;
-                               
+
                                if (cancellationFunc != null && cancellationFunc ())
                                        throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
                        }
-                       
+
                        T item;
                        while (!underlyingColl.TryTake (out item));
-                       
+
                        return item;
                }
-               
+
                public bool TryAdd (T item)
                {
                        return TryAdd (item, null, null);
                }
-               
+
                bool TryAdd (T item, Func<bool> contFunc, CancellationToken? token)
                {
                        do {
                                if (token.HasValue && token.Value.IsCancellationRequested)
                                        throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
-                               
+
                                long cachedAddId = addId;
                                long cachedRemoveId = removeId;
-                               
+
                                if (upperBound != -1) {
                                        if (cachedAddId - cachedRemoveId > upperBound) {
                                                continue;
                                        }
                                }
-                               
+
                                // Check our transaction id against completed stored one
                                if (isComplete.Value && cachedAddId >= completeId)
                                        throw new InvalidOperationException ("The BlockingCollection<T> has"
                                                                             + " been marked as complete with regards to additions.");
-                               
+
                                if (Interlocked.CompareExchange (ref addId, cachedAddId + 1, cachedAddId) != cachedAddId)
                                        continue;
-                       
+
                                if (!underlyingColl.TryAdd (item))
                                        throw new InvalidOperationException ("The underlying collection didn't accept the item.");
-                               
+
                                return true;
                        } while (contFunc != null && contFunc ());
-                       
+
                        return false;
                }
-               
+
                public bool TryAdd (T item, TimeSpan ts)
                {
                        return TryAdd (item, (int)ts.TotalMilliseconds);
                }
-               
+
                public bool TryAdd (T item, int millisecondsTimeout)
                {
                        Stopwatch sw = Stopwatch.StartNew ();
                        return TryAdd (item, () => sw.ElapsedMilliseconds < millisecondsTimeout, null);
                }
-               
+
                public bool TryAdd (T item, int millisecondsTimeout, CancellationToken token)
                {
                        Stopwatch sw = Stopwatch.StartNew ();
                        return TryAdd (item, () => sw.ElapsedMilliseconds < millisecondsTimeout, token);
                }
-               
+
                public bool TryTake (out T item)
                {
                        return TryTake (out item, null, null);
                }
-               
+
                bool TryTake (out T item, Func<bool> contFunc, CancellationToken? token)
                {
                        item = default (T);
-                       
+
                        do {
                                if (token.HasValue && token.Value.IsCancellationRequested)
                                        throw new OperationCanceledException ("The CancellationToken has had cancellation requested.");
-                               
+
                                long cachedRemoveId = removeId;
                                long cachedAddId = addId;
-                               
+
                                // Empty case
                                if (cachedRemoveId == cachedAddId) {
-                                       if (isComplete.Value && cachedRemoveId >= completeId)
-                                               continue;
-                                       
+                                       if (IsCompleted)
+                                               return false;
+
                                        continue;
                                }
-                               
+
                                if (Interlocked.CompareExchange (ref removeId, cachedRemoveId + 1, cachedRemoveId) != cachedRemoveId)
                                        continue;
-                               
+
                                return underlyingColl.TryTake (out item);
                        } while (contFunc != null && contFunc ());
-                       
+
                        return false;
                }
-               
+
                public bool TryTake (out T item, TimeSpan ts)
                {
                        return TryTake (out item, (int)ts.TotalMilliseconds);
                }
-               
+
                public bool TryTake (out T item, int millisecondsTimeout)
                {
                        item = default (T);
                        Stopwatch sw = Stopwatch.StartNew ();
-                       
+
                        return TryTake (out item, () => sw.ElapsedMilliseconds < millisecondsTimeout, null);
                }
-               
+
                public bool TryTake (out T item, int millisecondsTimeout, CancellationToken token)
                {
                        item = default (T);
                        Stopwatch sw = Stopwatch.StartNew ();
-                       
+
                        return TryTake (out item, () => sw.ElapsedMilliseconds < millisecondsTimeout, token);
                }
                #endregion
-               
+
                #region static methods
                static void CheckArray (BlockingCollection<T>[] collections)
                {
@@ -271,7 +269,7 @@ namespace System.Collections.Concurrent
                        if (collections.Length == 0 || IsThereANullElement (collections))
                                throw new ArgumentException ("The collections argument is a 0-length array or contains a null element.", "collections");
                }
-               
+
                static bool IsThereANullElement (BlockingCollection<T>[] collections)
                {
                        foreach (BlockingCollection<T> e in collections)
@@ -279,7 +277,7 @@ namespace System.Collections.Concurrent
                                        return true;
                        return false;
                }
-               
+
                public static int AddToAny (BlockingCollection<T>[] collections, T item)
                {
                        CheckArray (collections);
@@ -293,7 +291,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int AddToAny (BlockingCollection<T>[] collections, T item, CancellationToken token)
                {
                        CheckArray (collections);
@@ -307,7 +305,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryAddToAny (BlockingCollection<T>[] collections, T item)
                {
                        CheckArray (collections);
@@ -319,7 +317,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryAddToAny (BlockingCollection<T>[] collections, T item, TimeSpan ts)
                {
                        CheckArray (collections);
@@ -331,7 +329,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryAddToAny (BlockingCollection<T>[] collections, T item, int millisecondsTimeout)
                {
                        CheckArray (collections);
@@ -343,7 +341,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryAddToAny (BlockingCollection<T>[] collections, T item, int millisecondsTimeout,
                                               CancellationToken token)
                {
@@ -356,7 +354,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TakeFromAny (BlockingCollection<T>[] collections, out T item)
                {
                        item = default (T);
@@ -371,7 +369,7 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TakeFromAny (BlockingCollection<T>[] collections, out T item, CancellationToken token)
                {
                        item = default (T);
@@ -386,11 +384,11 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item)
                {
                        item = default (T);
-                       
+
                        CheckArray (collections);
                        int index = 0;
                        foreach (var coll in collections) {
@@ -400,11 +398,11 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, TimeSpan ts)
                {
                        item = default (T);
-                       
+
                        CheckArray (collections);
                        int index = 0;
                        foreach (var coll in collections) {
@@ -414,11 +412,11 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, int millisecondsTimeout)
                {
                        item = default (T);
-                       
+
                        CheckArray (collections);
                        int index = 0;
                        foreach (var coll in collections) {
@@ -428,12 +426,12 @@ namespace System.Collections.Concurrent
                        }
                        return -1;
                }
-               
+
                public static int TryTakeFromAny (BlockingCollection<T>[] collections, out T item, int millisecondsTimeout,
                                                  CancellationToken token)
                {
                        item = default (T);
-                       
+
                        CheckArray (collections);
                        int index = 0;
                        foreach (var coll in collections) {
@@ -444,110 +442,113 @@ namespace System.Collections.Concurrent
                        return -1;
                }
                #endregion
-               
+
                public void CompleteAdding ()
                {
                  // No further add beside that point
                  completeId = addId;
                  isComplete.Value = true;
                }
-               
+
                void ICollection.CopyTo (Array array, int index)
                {
                        underlyingColl.CopyTo (array, index);
                }
-               
+
                public void CopyTo (T[] array, int index)
                {
                        underlyingColl.CopyTo (array, index);
                }
-               
+
                public IEnumerable<T> GetConsumingEnumerable ()
                {
                        return GetConsumingEnumerable (Take);
                }
-               
+
                public IEnumerable<T> GetConsumingEnumerable (CancellationToken token)
                {
                        return GetConsumingEnumerable (() => Take (token));
                }
-               
+
                IEnumerable<T> GetConsumingEnumerable (Func<T> getFunc)
                {
                        while (true) {
                                T item = default (T);
-                               
+
                                try {
                                        item = getFunc ();
                                } catch {
                                        break;
                                }
-                               
+
                                yield return item;
                        }
                }
-               
+
                IEnumerator IEnumerable.GetEnumerator ()
                {
                        return ((IEnumerable)underlyingColl).GetEnumerator ();
                }
-               
+
                IEnumerator<T> IEnumerable<T>.GetEnumerator ()
                {
                        return ((IEnumerable<T>)underlyingColl).GetEnumerator ();
                }
-               
+
                public void Dispose ()
                {
-                       
+
                }
-               
+
                protected virtual void Dispose (bool managedRes)
                {
-                       
+
                }
-               
+
                public T[] ToArray ()
                {
                        return underlyingColl.ToArray ();
                }
                
+               [ThreadStatic]
+               SpinWait sw;
+
                // Method used to stall the thread for a limited period of time before retrying an operation
                void Block ()
                {
                        sw.SpinOnce ();
                }
-               
+
                public int BoundedCapacity {
                        get {
                                return upperBound;
                        }
                }
-               
+
                public int Count {
                        get {
                                return underlyingColl.Count;
                        }
                }
-               
+
                public bool IsAddingCompleted {
                        get {
                                return isComplete.Value;
                        }
                }
-               
+
                public bool IsCompleted {
                        get {
                                return isComplete.Value && addId == removeId;
                        }
                }
-               
+
                object ICollection.SyncRoot {
                        get {
                                return underlyingColl.SyncRoot;
                        }
                }
-               
+
                bool ICollection.IsSynchronized {
                        get {
                                return underlyingColl.IsSynchronized;
index 3c0f5605c6b00b553aa9feaf7bd393b989d0f21b..e16569fc2d998c8c1a40988245f7f1e5c80f7195 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * BlockingCollection.cs:
+       * ConcurrentBag.cs: Add BOOTSTRAP_NET_4_0
+
 2009-12-03  Marek Safar  <marek.safar@gmail.com>
 
        * BlockingCollection.cs, ConcurrentBag.cs: Updated to Beta 2 API.
index 02fcc03e974d56a04b61e9eef9510a51b166f103..984a4a69767459c78fa7b7642e45309fa623949a 100644 (file)
@@ -41,8 +41,8 @@ namespace System.Collections.Concurrent
        [DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
        public class ConcurrentBag<T> : IProducerConsumerCollection<T>, IEnumerable<T>, IEnumerable
        {
+               const int multiplier = 2;
                int size = Environment.ProcessorCount + 1;
-               int multiplier = 2;
                int count;
                
                CyclicDeque<T>[] container;
index 401f7264dc3c3b8a05f135dda991b4929b973d42..8b7efcc3eccc5c360d381a7aa637783191ccccaa 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // Barrier.cs
 //  
@@ -31,7 +31,7 @@ namespace System.Threading
 {
        public class Barrier : IDisposable
        {
-               const int MAX_PARTICIPANTS = 32767;
+               const int MaxParticipants = 32767;
                Action<Barrier> postPhaseAction;
                
                int participants;
@@ -45,7 +45,7 @@ namespace System.Threading
                
                public Barrier (int participants, Action<Barrier> postPhaseAction)
                {
-                       if (participants < 0 || participants > MAX_PARTICIPANTS)
+                       if (participants < 0 || participants > MaxParticipants)
                                throw new ArgumentOutOfRangeException ("participants");
                        
                        this.participants = participants;
@@ -120,6 +120,7 @@ namespace System.Threading
                        
                        if (cntd.Signal (participantCount))
                                PostPhaseAction (cleaned);
+
                        Interlocked.Add (ref participants, -participantCount);
                }
                
index 08e84cbd0498a1a41cfccc593eb58d93682cc523..1a3c6005e14b744d6e29a60de1f08b4bd321f0c1 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Barrier.cs: Add BOOTSTRAP_NET_4_0
+
 2010-04-06  Jb Evain  <jbevain@novell.com>
 
        * SemaphoreFullException.cs: moved to corlib in net_4_0.
index 7bf258b8f23ea62143efbf1826e202a936d8ca5d..310e0b3467b47d87cee2c7b805512df6d7571582 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * ConcurrentDictionary.cs:
+       * ConcurrentSkipList.cs:
+       * OrderablePartitioner.cs:
+       * Partitioner.cs: Add BOOTSTRAP_NET_4_0 define
+
 2010-03-24  Jérémie Laval  <jeremie.laval@gmail.com>
 
        * ConcurrentDictionary.cs: Remove while looping
index bf4e160a430e994a1daad94ab136b1cf2b519cf4..fb0774cee2ea84a6e69134fbfa6b13bc0f294fd6 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // ConcurrentSkipList.cs
 //
 // Copyright (c) 2009 Jérémie "Garuma" Laval
@@ -29,6 +28,8 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.Serialization;
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 namespace System.Collections.Concurrent
 {
        public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
@@ -126,6 +127,8 @@ namespace System.Collections.Concurrent
 
                public bool TryAdd (TKey key, TValue value)
                {
+                       if (key == null)
+                               throw new ArgumentNullException ("key");
                        Basket basket;
                        bool taken = false;
 
index 247b5059756e2813fa7215609cf1ae95fe374090..e8c637f7ebd5d2b46797da33bb0b148c1cda880a 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // ConcurrentSkipList.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 1872c00e1d1279923cb7178eda415bee4902fc4a..9b2c8a41281d822eb68ee9a12db9bb0408aa716e 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // 
 // OrderablePartitioner.cs
 //  
@@ -28,6 +27,8 @@
 using System;
 using System.Collections.Generic;
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 namespace System.Collections.Concurrent
 {
        public abstract class OrderablePartitioner<TSource> : Partitioner<TSource>
index 24987ae73bc058ad7c15a32bc6e1165a3df1a0b7..03ca175dcb63b574e71146afa3c9c4d19730e404 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // 
 // Partitioner.cs
 //  
@@ -28,6 +27,8 @@
 using System;
 using System.Collections.Generic;
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 namespace System.Collections.Concurrent
 {
        public static class Partitioner
index da1166776ac96bb09a9bbf2344c3361c0d560974..23df7f7c760fbb44a3dc13dee60e1b31b60fa632 100644 (file)
@@ -1,5 +1,3 @@
-#if NET_4_0
-#define USE_MONITOR
 // 
 // EnumerablePartitioner.cs
 //  
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 using System;
+using System.Threading.Tasks;
 using System.Collections.Generic;
 
 namespace System.Collections.Concurrent
 {
+       // Represent a chunk partitioner
        internal class EnumerablePartitioner<T> : OrderablePartitioner<T>
        {
                IEnumerable<T> source;
-#if USE_MONITOR
-               object syncLock = new object ();
-#endif
+               
                const int InitialPartitionSize = 1;
                const int PartitionMultiplier = 2;
                
+               int initialPartitionSize;
+               int partitionMultiplier;
+               
                int index = 0;
+               readonly object syncLock = new object ();
                
-               public EnumerablePartitioner (IEnumerable<T> source) : base (true, false, true)
+               public EnumerablePartitioner (IEnumerable<T> source)
+                       : this (source, InitialPartitionSize, PartitionMultiplier)
+               {
+
+               }
+               
+               // This is used to get striped partitionning (for Take and Skip for instance
+               public EnumerablePartitioner (IEnumerable<T> source, int initialPartitionSize, int partitionMultiplier)
+                        : base (true, false, true)
                {
                        this.source = source;
+                       this.initialPartitionSize = initialPartitionSize;
+                       this.partitionMultiplier = partitionMultiplier;
                }
                
                public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions (int partitionCount)
@@ -66,7 +80,7 @@ namespace System.Collections.Concurrent
                
                IEnumerator<KeyValuePair<long, T>> GetPartitionEnumerator (IEnumerator<T> src)
                {
-                       int count = InitialPartitionSize;
+                       int count = initialPartitionSize;
                        List<T> list = new List<T> ();
                        
                        while (true) {
@@ -89,12 +103,14 @@ namespace System.Collections.Concurrent
                                        }                                       
                                }
                                
+                               
+                               
                                for (int i = 0; i < list.Count; i++)
                                        yield return new KeyValuePair<long, T> (ind + i, list[i]);
                                
-                               count *= PartitionMultiplier;
+                               count *= partitionMultiplier;
                        }
                }                                  
        }
 }
-#endif
\ No newline at end of file
+#endif
index 37b0fdddfc2ae98e2ce96f4cbee572974b2b1a9d..1554a5d46fd1747b4bcce6bf684f43c6191d763b 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // 
 // ListPartitioner.cs
 //  
 using System;
 using System.Collections.Generic;
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 namespace System.Collections.Concurrent
 {
+       // Represent a Range partitioner
        internal class ListPartitioner<T> : OrderablePartitioner<T>
        {
                IList<T> source;
+               readonly bool chunking = Environment.GetEnvironmentVariable ("PLINQ_PARTITIONING_HINT") == "chunking";
                
                public ListPartitioner (IList<T> source) : base (true, true, true)
                {
@@ -47,9 +50,15 @@ namespace System.Collections.Concurrent
                        IEnumerator<KeyValuePair<long, T>>[] enumerators
                                = new IEnumerator<KeyValuePair<long, T>>[partitionCount];
                        
-                       int count = (source.Count >= partitionCount) ? source.Count / partitionCount : 1;
+                       int count = GetBestCacheLineSize (source.Count, partitionCount);
                        
                        for (int i = 0; i < enumerators.Length; i++) {
+                               if (chunking) {
+                                       const int step = 64;
+                                       enumerators[i] = GetEnumeratorForRange (i * step, enumerators.Length, source.Count, step);
+                                       continue;
+                               }
+                               
                                if (i != enumerators.Length - 1)
                                        enumerators[i] = GetEnumeratorForRange (i * count, i * count + count);
                                else
@@ -59,6 +68,20 @@ namespace System.Collections.Concurrent
                        return enumerators;
                }
                
+               int GetBestCacheLineSize (int initialSize, int partitionCount)  
+               {
+                       const int numPartition = 20;
+                       uint size = (uint)(initialSize / partitionCount / numPartition);
+                       int count = 0;
+                       
+                       if (size <= 1)
+                               return 1;
+                       
+                       while ((size <<= 1) < 0x80000040)
+                               ++count;
+                       return (int)(0x80000040 >> (count + 1));
+               }
+               
                IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRange (int startIndex, int lastIndex)
                {
                        if (startIndex >= source.Count)
@@ -66,11 +89,19 @@ namespace System.Collections.Concurrent
                        
                        return GetEnumeratorForRangeInternal (startIndex, lastIndex);
                }
+               
+               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRange (int startIndex, int stride, int count, int step)
+               {
+                       if (startIndex >= source.Count)
+                         return GetEmpty ();
+                       
+                       return GetEnumeratorForRangeInternal (startIndex, stride, count, step);
+               }
 
                IEnumerator<KeyValuePair<long, T>> GetEmpty ()
-                 {
+               {
                        yield break;
-                 }
+               }
                
                IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRangeInternal (int startIndex, int lastIndex)
                {       
@@ -78,6 +109,15 @@ namespace System.Collections.Concurrent
                                yield return new KeyValuePair<long, T> (i, source[i]);
                        }
                }
+               
+               IEnumerator<KeyValuePair<long, T>> GetEnumeratorForRangeInternal (int startIndex, int stride, int count, int step)
+               {
+                       for (int i = startIndex; i < count; i += stride * step) {
+                               for (int j = i; j < i + step && j < count; j++) {
+                                       yield return new KeyValuePair<long, T> (j, source[j]);
+                               }
+                       }
+               }
        }
 }
-#endif
\ No newline at end of file
+#endif
index 22fdde9768a6d0f88cd2f4d6ab06604eef6041c6..49f6156515541f1ef84c491c2fbcf9e870ebb4dc 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * IStructuralComparable.cs:
+       * IStructuralEquatable.cs: Add BOOTSTRAP_NET_4_0 define
+
 2010-03-19  Sebastien Pouliot  <sebastien@ximian.com>
 
        * CollectionDebuggerView.cs: Change to internal so we can avoid
index f7695f9ac81cbedcdf5b2625b27248a09feaa86e..4850749e69fb972edf8efc36f100e14b24499617 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if MOONLIGHT || NET_4_0
+#if MOONLIGHT || NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System;
 
index a3d4ef5117a466722c70438213d9acc17cc2e07d..444d44f8fe70de08965279f940654c7eeb6a0e43 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if MOONLIGHT || NET_4_0
+#if MOONLIGHT || NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System;
 
index 2992cdbb9bb9dc06135f83e53af76a2948c87607..97e61717007e81308cf7a74612f8f6dd2c182d8b 100644 (file)
@@ -1,3 +1,14 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Future.cs:
+       * Task.cs:
+       * TaskCanceledException.cs:
+       * TaskContinuationOptions.cs:
+       * TaskCreationOptions.cs:
+       * TaskFactory.cs:
+       * TaskScheduler.cs:
+       * TaskStatus.cs: Add BOOTSTRAP_NET_4_0 define
+
 2010-03-02  Jérémie Laval  <jeremie.laval@gmail.com>
 
        * Task.cs: If we add a continuation when the Task is already finished
index 8dd142403a8dba2ec26f42d4935a3487138d9808..ecb11b2b868ddb5d98bc135d51836ca38169cf81 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // Future.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 66001c7b4e00123f56ad6139dbf05f879bea3844..98ebf3573b1acb9be3f4b3692221f099f49fbde0 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // CyclicDeque.cs
 //  
@@ -198,4 +198,4 @@ namespace System.Threading.Tasks
                }
        }
 }
-#endif
\ No newline at end of file
+#endif
index 3b205696f1166e55ba276c6df36a47e4d5f9c455..536f368bb3847fdc48e12c47bcf5b0ec96160ec8 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // IScheduler.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 28d5a0f6fbfeb87b34a630827ee6d1833f6fbfd6..5b65790cec1f9ee85258fa727baedf1e0a67a89f 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // Scheduler.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index cd6307105d6a17c14545a5c080dffe3b54cabf9c..713a61cf7424fea7d1d9b15212f39ba4b17d1aa3 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // SchedulerProxy.cs
 //  
index cad86d43482e06fb89789785fd5b52416f73170c..50b1fcd41beba222d677ce51653b08c827c2fb6a 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // ThreadWorker.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
@@ -100,6 +100,7 @@ namespace System.Threading.Tasks
        
                                this.workerThread.IsBackground = true;
                                this.workerThread.Priority = priority;
+                               this.workerThread.Name = "ParallelFxThreadWorker";
                        };
                        threadInitializer ();
                }
index ae6fb42636341011ffcd846da9bf6fc74f7384b7..acc2b5aa1fd00a12a83c3229be80236635ca751a 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // Task.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
@@ -23,6 +22,8 @@
 //
 //
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 using System;
 using System.Threading;
 using System.Collections.Concurrent;
index e06902099829238be89a3fec8e19d4e3f3b56fb8..23ec35ac2d530d4360ea63d09debbe0d0655d846 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // TaskCanceledException.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 49d8329577c19f4e209bffc37b8affc630cf57ea..a5205523c7232b5044ce79e8629d36b01a6a6e3e 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // TaskContinuationKind.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 23d1a7f0256813420a4de64c16b92d44cfddd11f..3af2c965b94a21894d3fba33dca9744affde8405 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // TaskCreationOptions.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 49fc5574d06d8bd05a31e33df84df93e48fb7aa6..d69c9cd1e8778a3160b3def4e3aa3b72b6d2ebc8 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // TaskFactory.cs
 //  
index bcef0cd8cef10c64572a897f095efddb3832e493..e836e6e4856c5aa76850bdbe04c40b1636543eac 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // TaskScheduler.cs
 //  
index 851437013ffccbb3987bc71f5b829564cf316de4..ff9060220874cf1802fe9647c8256a19e421cb67 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // TaskStatus.cs
 //  
index c91bde8ec16f5650bac2bc459ddbc16ff5cfc9f7..3c76f0925f539044609117c52229c9f4e0bef932 100644 (file)
@@ -1,4 +1,4 @@
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 // AtomicBoolean.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
index 050e42627f369688a5f1b7672b9b88f8dd1f0c63..533d11fddbcd353d5797ae51a73992948fcec314 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * AtomicBoolean.cs:
+       * CountdownEvent.cs:
+       * SpinLock.cs: Add BOOTSTRAP_NET_4_0 define
+
 2010-03-25 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * ThreadPool.cs: add fast path to queue work items in the runtime.
index 0a53f30e5244c7124dcae24597c67345aba019a3..c12c85ed67c632f7ae45f44c10e0d45630cdf851 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0 || BOOTSTRAP_NET_4_0
 // CountdownEvent.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
@@ -25,6 +24,8 @@
 
 using System;
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 namespace System.Threading
 {      
        public class CountdownEvent : IDisposable
index 92fab359e3611a48ccacb125e95ccc68179de52f..e3fb372dd26551be9327ea5a6349eacb7a0e5eab 100644 (file)
@@ -26,7 +26,7 @@ using System;
 using System.Runtime.ConstrainedExecution;
 using System.Runtime.InteropServices;
 
-#if NET_4_0
+#if NET_4_0 || BOOTSTRAP_NET_4_0
 namespace System.Threading
 {
        [StructLayout(LayoutKind.Explicit)]
index cb2d5cea921ece808c4abfc5786d0985a29962f5..9d4d3f4abb4b6703760c2bb49e8ad7de220a2e85 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-15  Jérémie Laval  <jeremie.laval@gmail.com>
+
+       * Tuple.cs:
+       * Tuples.cs: Add BOOTSTRAP_NET_4_0 define
+
 2010-04-13 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * MonoCustomAttrs.cs: Raise an exception if the runtime
index 081071787274f5ede65ec79f14fcbe181954b7ac..b535413c12ddb56cb241d97707da23764f5ea203 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if MOONLIGHT || NET_4_0
+#if MOONLIGHT || NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System;
 
index 6404a923303e33b3104001b92a63f7cb2279e1ae..e5e8f6ec2199da93443b365eaecda01fafe6bbfb 100644 (file)
@@ -27,7 +27,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if MOONLIGHT || NET_4_0
+#if MOONLIGHT || NET_4_0 || BOOTSTRAP_NET_4_0
 
 using System;
 using System.Collections;