Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / Tasks / ParallelLoopState.cs / 1305376 / ParallelLoopState.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ParallelState.cs // //[....] // // A non-generic and generic parallel state class, used by the Parallel helper class // for parallel loop management. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- using System.Diagnostics; using System.Security.Permissions; using System.Diagnostics.Contracts; // Prevents compiler warnings/errors regarding the use of ref params in Interlocked methods #pragma warning disable 0420 namespace System.Threading.Tasks { ////// Enables iterations of [HostProtection(Synchronization = true, ExternalThreading = true)] [DebuggerDisplay("ShouldExitCurrentIteration = {ShouldExitCurrentIteration}")] public class ParallelLoopState { // Derived classes will track a ParallelStateFlags32 or ParallelStateFlags64. // So this is slightly redundant, but it enables us to implement some // methods in this base class. private ParallelLoopStateFlags m_flagsBase; internal ParallelLoopState(ParallelLoopStateFlags fbase) { m_flagsBase = fbase; } ///loops to interact with /// other iterations. /// /// Internal/virtual support for ShouldExitCurrentIteration. /// internal virtual bool InternalShouldExitCurrentIteration { get { Contract.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } } ////// Gets whether the current iteration of the loop should exit based /// on requests made by this or other iterations. /// ////// When an iteration of a loop calls public bool ShouldExitCurrentIteration { get { return InternalShouldExitCurrentIteration; } } ///or , or /// when one throws an exception, or when the loop is canceled, the class will proactively /// attempt to prohibit additional iterations of the loop from starting execution. /// However, there may be cases where it is unable to prevent additional iterations from starting. /// It may also be the case that a long-running iteration has already begun execution. In such /// cases, iterations may explicitly check the property and /// cease execution if the property returns true. /// /// Gets whether any iteration of the loop has called public bool IsStopped { get { return ((m_flagsBase.LoopStateFlags & ParallelLoopStateFlags.PLS_STOPPED) != 0); } } ///. /// /// Gets whether any iteration of the loop has thrown an exception that went unhandled by that /// iteration. /// public bool IsExceptional { get { return ((m_flagsBase.LoopStateFlags & ParallelLoopStateFlags.PLS_EXCEPTIONAL) != 0); } } ////// Internal/virtual support for LowestBreakIteration. /// internal virtual long? InternalLowestBreakIteration { get { Contract.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } } ////// Gets the lowest iteration of the loop from which ///was called. /// /// If no iteration of the loop called public long? LowestBreakIteration { get { return InternalLowestBreakIteration; } } ///, this property will return null. /// /// Communicates that the ///loop should cease execution at the system's earliest /// convenience. /// /// The ///method was previously called. and may not be used in combination by iterations of the same loop. /// /// public void Stop() { m_flagsBase.Stop(); } // Internal/virtual support for Break(). internal virtual void InternalBreak() { Contract.Assert(false); throw new NotSupportedException( Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod")); } ////// ///may be used to communicate to the loop that no other iterations need be run. /// For long-running iterations that may already be executing, causes /// to return true for all other iterations of the loop, such that another iteration may check and exit early if it's observed to be true. /// /// ///is typically employed in search-based algorithms, where once a result is found, /// no other iterations need be executed. /// /// Communicates that the ///loop should cease execution at the system's earliest /// convenience of iterations beyond the current iteration. /// /// The ///method was previously called. and /// may not be used in combination by iterations of the same loop. /// /// public void Break() { InternalBreak(); } // Helper method to avoid repeating Break() logic between ParallelState32 and ParallelState32/// ///may be used to communicate to the loop that no other iterations after the /// current iteration need be run. For example, if is called from the 100th /// iteration of a for loop iterating in parallel from 0 to 1000, all iterations less than 100 should /// still be run, but the iterations from 101 through to 1000 are not necessary. /// /// For long-running iterations that may already be executing, ///causes /// to be set to the current iteration's index if the current index is less than the current value of /// . /// /// ///is typically employed in search-based algorithms where an ordering is /// present in the data source. /// internal static void Break(int iteration, ParallelLoopStateFlags32 pflags) { int oldValue = ParallelLoopStateFlags.PLS_NONE; // Attempt to change state from "not stopped or broken or canceled or exceptional" to "broken". if (!pflags.AtomicLoopStateUpdate(ParallelLoopStateFlags.PLS_BROKEN, ParallelLoopStateFlags.PLS_STOPPED | ParallelLoopStateFlags.PLS_EXCEPTIONAL | ParallelLoopStateFlags.PLS_CANCELED, ref oldValue)) { // If we were already stopped, we have a problem if ((oldValue & ParallelLoopStateFlags.PLS_STOPPED) != 0) { throw new InvalidOperationException( Environment.GetResourceString("ParallelState_Break_InvalidOperationException_BreakAfterStop")); } else { // Apparently we previously got cancelled or became exceptional. No action necessary return; } } // replace shared LowestBreakIteration with CurrentIteration, but only if CurrentIteration // is less than LowestBreakIteration. int oldLBI = pflags.m_lowestBreakIteration; if (iteration < oldLBI) { SpinWait wait = new SpinWait(); while (Interlocked.CompareExchange( ref pflags.m_lowestBreakIteration, iteration, oldLBI) != oldLBI) { wait.SpinOnce(); oldLBI = pflags.m_lowestBreakIteration; if (iteration > oldLBI) break; } } } // Helper method to avoid repeating Break() logic between ParallelState64 and ParallelState64 internal static void Break(long iteration, ParallelLoopStateFlags64 pflags) { int oldValue = ParallelLoopStateFlags.PLS_NONE; // Attempt to change state from "not stopped or broken or canceled or exceptional" to "broken". if (!pflags.AtomicLoopStateUpdate(ParallelLoopStateFlags.PLS_BROKEN, ParallelLoopStateFlags.PLS_STOPPED | ParallelLoopStateFlags.PLS_EXCEPTIONAL | ParallelLoopStateFlags.PLS_CANCELED, ref oldValue)) { // If we were already stopped, we have a problem if ((oldValue & ParallelLoopStateFlags.PLS_STOPPED) != 0) { throw new InvalidOperationException( Environment.GetResourceString("ParallelState_Break_InvalidOperationException_BreakAfterStop")); } else { // Apparently we previously got cancelled or became exceptional. No action necessary return; } } // replace shared LowestBreakIteration with CurrentIteration, but only if CurrentIteration // is less than LowestBreakIteration. long oldLBI = pflags.LowestBreakIteration; if (iteration < oldLBI) { SpinWait wait = new SpinWait(); while (Interlocked.CompareExchange( ref pflags.m_lowestBreakIteration, iteration, oldLBI) != oldLBI) { wait.SpinOnce(); oldLBI = pflags.LowestBreakIteration; if (iteration > oldLBI) break; } } } } internal class ParallelLoopState32 : ParallelLoopState { private ParallelLoopStateFlags32 m_sharedParallelStateFlags; private int m_currentIteration = 0; /// /// Internal constructor to ensure an instance isn't created by users. /// /// A flag shared among all threads participating /// in the execution of a certain loop. internal ParallelLoopState32(ParallelLoopStateFlags32 sharedParallelStateFlags) : base(sharedParallelStateFlags) { m_sharedParallelStateFlags = sharedParallelStateFlags; } ////// Tracks the current loop iteration for the owning task. /// This is used to compute whether or not the task should /// terminate early due to a Break() call. /// internal int CurrentIteration { get { return m_currentIteration; } set { m_currentIteration = value; } } ////// Returns true if we should be exiting from the current iteration /// due to Stop(), Break() or exception. /// internal override bool InternalShouldExitCurrentIteration { get { return m_sharedParallelStateFlags.ShouldExitLoop(CurrentIteration); } } ////// Returns the lowest iteration at which Break() has been called, or /// null if Break() has not yet been called. /// internal override long? InternalLowestBreakIteration { get {return m_sharedParallelStateFlags.NullableLowestBreakIteration; } } ////// Communicates that parallel tasks should stop when they reach a specified iteration element. /// (which is CurrentIteration of the caller). /// ///Break() called after Stop(). ////// This is shared with all other concurrent threads in the system which are participating in the /// loop's execution. After calling Break(), no additional iterations will be executed on /// the current thread, and other worker threads will execute once they get beyond the calling iteration. /// internal override void InternalBreak() { ParallelLoopState.Break(CurrentIteration, m_sharedParallelStateFlags); } } ////// Allows independent iterations of a parallel loop to interact with other iterations. /// internal class ParallelLoopState64 : ParallelLoopState { private ParallelLoopStateFlags64 m_sharedParallelStateFlags; private long m_currentIteration = 0; ////// Internal constructor to ensure an instance isn't created by users. /// /// A flag shared among all threads participating /// in the execution of a certain loop. internal ParallelLoopState64(ParallelLoopStateFlags64 sharedParallelStateFlags) : base(sharedParallelStateFlags) { m_sharedParallelStateFlags = sharedParallelStateFlags; } ////// Tracks the current loop iteration for the owning task. /// This is used to compute whether or not the task should /// terminate early due to a Break() call. /// internal long CurrentIteration { // No interlocks needed, because this value is only accessed in a single thread. get {return m_currentIteration;} set {m_currentIteration = value; } } ////// Returns true if we should be exiting from the current iteration /// due to Stop(), Break() or exception. /// internal override bool InternalShouldExitCurrentIteration { get { return m_sharedParallelStateFlags.ShouldExitLoop(CurrentIteration); } } ////// Returns the lowest iteration at which Break() has been called, or /// null if Break() has not yet been called. /// internal override long? InternalLowestBreakIteration { // We don't need to worry about torn read/write here because // ParallelStateFlags64.LowestBreakIteration property is protected // by an Interlocked.Read(). get { return m_sharedParallelStateFlags.NullableLowestBreakIteration; } } ////// Communicates that parallel tasks should stop when they reach a specified iteration element. /// (which is CurrentIteration of the caller). /// ///Break() called after Stop(). ////// Atomically sets shared StoppedBroken flag to BROKEN, then atomically sets shared /// LowestBreakIteration to CurrentIteration, but only if CurrentIteration is less than /// LowestBreakIteration. /// internal override void InternalBreak() { ParallelLoopState.Break(CurrentIteration, m_sharedParallelStateFlags); } } ////// State information that is common between ParallelStateFlags class /// and ParallelStateFlags64 class. /// internal class ParallelLoopStateFlags { internal static int PLS_NONE; internal static int PLS_EXCEPTIONAL = 1; internal static int PLS_BROKEN = 2; internal static int PLS_STOPPED = 4; internal static int PLS_CANCELED = 8; private volatile int m_LoopStateFlags = PLS_NONE; internal int LoopStateFlags { get { return m_LoopStateFlags; } } internal bool AtomicLoopStateUpdate(int newState, int illegalStates) { int oldState = 0; return AtomicLoopStateUpdate(newState, illegalStates, ref oldState); } internal bool AtomicLoopStateUpdate(int newState, int illegalStates, ref int oldState) { SpinWait sw = new SpinWait(); do { oldState = m_LoopStateFlags; if ((oldState & illegalStates) != 0) return false; if (Interlocked.CompareExchange(ref m_LoopStateFlags, oldState | newState, oldState) == oldState) { return true; } sw.SpinOnce(); } while (true); } internal void SetExceptional() { // we can set the exceptional flag regardless of the state of other bits. AtomicLoopStateUpdate(PLS_EXCEPTIONAL, PLS_NONE); } internal void Stop() { // disallow setting of PLS_STOPPED bit only if PLS_BROKEN was already set if (!AtomicLoopStateUpdate(PLS_STOPPED, PLS_BROKEN)) { throw new InvalidOperationException( Environment.GetResourceString("ParallelState_Stop_InvalidOperationException_StopAfterBreak")); } } // Returns true if StoppedBroken is updated to PLS_CANCELED. internal bool Cancel() { // we can set the canceled flag regardless of the state of other bits. return (AtomicLoopStateUpdate(PLS_CANCELED, PLS_NONE)); } } ////// An internal class used to share accounting information in 32-bit versions /// of For()/ForEach() loops. /// internal class ParallelLoopStateFlags32 : ParallelLoopStateFlags { // Records the lowest iteration at which a Break() has been called, // or Int32.MaxValue if no break has been called. Used directly // by Break(). internal volatile int m_lowestBreakIteration = Int32.MaxValue; // Not strictly necessary, but maintains consistency with ParallelStateFlags64 internal int LowestBreakIteration { get { return m_lowestBreakIteration; } } // Does some processing to convert m_lowestBreakIteration to a long?. internal long? NullableLowestBreakIteration { get { if (m_lowestBreakIteration == Int32.MaxValue) return null; else { // protect against torn read of 64-bit value long rval = m_lowestBreakIteration; if (IntPtr.Size >= 8) return rval; else return Interlocked.Read(ref rval); } } } ////// Lets the caller know whether or not to prematurely exit the For/ForEach loop. /// If this returns true, then exit the loop. Otherwise, keep going. /// /// The caller's current iteration point /// in the loop. ////// The loop should exit on any one of the following conditions: /// (1) Stop() has been called by one or more tasks. /// (2) An exception has been raised by one or more tasks. /// (3) Break() has been called by one or more tasks, and /// CallerIteration exceeds the (lowest) iteration at which /// Break() was called. /// (4) The loop was canceled. /// internal bool ShouldExitLoop(int CallerIteration) { int flags = LoopStateFlags; return (flags != PLS_NONE && ( ((flags & (PLS_EXCEPTIONAL | PLS_STOPPED | PLS_CANCELED)) != 0) || (((flags & PLS_BROKEN) != 0) && (CallerIteration > LowestBreakIteration)))); } // This lighter version of ShouldExitLoop will be used when the body type doesn't contain a state. // Since simpler bodies cannot stop or break, we can safely skip checks for those flags here. internal bool ShouldExitLoop() { int flags = LoopStateFlags; return ((flags != PLS_NONE) && ((flags & (PLS_EXCEPTIONAL | PLS_CANCELED)) != 0)); } } ////// An internal class used to share accounting information in 64-bit versions /// of For()/ForEach() loops. /// internal class ParallelLoopStateFlags64 : ParallelLoopStateFlags { // Records the lowest iteration at which a Break() has been called, // or Int64.MaxValue if no break has been called. Used directly // by Break(). internal long m_lowestBreakIteration = Int64.MaxValue; // Performs a conditionally interlocked read of m_lowestBreakIteration. internal long LowestBreakIteration { get { if (IntPtr.Size >= 8) return m_lowestBreakIteration; else return Interlocked.Read(ref m_lowestBreakIteration); } } // Does some processing to convert m_lowestBreakIteration to a long?. internal long? NullableLowestBreakIteration { get { if (m_lowestBreakIteration == Int64.MaxValue) return null; else { if (IntPtr.Size >= 8) return m_lowestBreakIteration; else return Interlocked.Read(ref m_lowestBreakIteration); } } } ////// Lets the caller know whether or not to prematurely exit the For/ForEach loop. /// If this returns true, then exit the loop. Otherwise, keep going. /// /// The caller's current iteration point /// in the loop. ////// The loop should exit on any one of the following conditions: /// (1) Stop() has been called by one or more tasks. /// (2) An exception has been raised by one or more tasks. /// (3) Break() has been called by one or more tasks, and /// CallerIteration exceeds the (lowest) iteration at which /// Break() was called. /// (4) The loop has been canceled. /// internal bool ShouldExitLoop(long CallerIteration) { int flags = LoopStateFlags; return (flags != PLS_NONE && ( ((flags & (PLS_EXCEPTIONAL | PLS_STOPPED | PLS_CANCELED)) != 0) || (((flags & PLS_BROKEN) != 0) && (CallerIteration > LowestBreakIteration)))); } // This lighter version of ShouldExitLoop will be used when the body type doesn't contain a state. // Since simpler bodies cannot stop or break, we can safely skip checks for those flags here. internal bool ShouldExitLoop() { int flags = LoopStateFlags; return ((flags != PLS_NONE) && ((flags & (PLS_EXCEPTIONAL | PLS_CANCELED)) != 0)); } } ////// Provides completion status on the execution of a ///loop. /// /// If public struct ParallelLoopResult { internal bool m_completed; internal long? m_lowestBreakIteration; ///returns true, then the loop ran to completion, such that all iterations /// of the loop were executed. If returns false and returns null, a call to was used to end the loop prematurely. If returns false and returns a non-null integral /// value, was used to end the loop prematurely. /// /// Gets whether the loop ran to completion, such that all iterations of the loop were executed /// and the loop didn't receive a request to end prematurely. /// public bool IsCompleted { get { return m_completed; } } ////// Gets the index of the lowest iteration from which ////// was called. /// /// If public long? LowestBreakIteration { get { return m_lowestBreakIteration; } } } } #pragma warning restore 0420 // File provided for Reference Use Only by Microsoft Corporation (c) 2007.was not employed, this property will /// return null. ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SynchronizationValidator.cs
- Helper.cs
- MailWebEventProvider.cs
- XmlTextReader.cs
- SqlColumnizer.cs
- TextRangeEdit.cs
- OciHandle.cs
- HttpRequestTraceRecord.cs
- ApplicationManager.cs
- __Filters.cs
- TypeInfo.cs
- GeneralTransform3DGroup.cs
- PlaceHolder.cs
- CurrentChangedEventManager.cs
- DoWorkEventArgs.cs
- FixedDocumentPaginator.cs
- Base64Stream.cs
- Stream.cs
- FilterException.cs
- NativeMethods.cs
- CharacterString.cs
- PropertyItemInternal.cs
- TryExpression.cs
- StackSpiller.cs
- Zone.cs
- StringConcat.cs
- SerializationInfoEnumerator.cs
- ProxyWebPartConnectionCollection.cs
- SByteConverter.cs
- CodeRegionDirective.cs
- DataGridPagerStyle.cs
- RelationshipEndCollection.cs
- AppDomainFactory.cs
- TemplateBindingExpressionConverter.cs
- WindowsButton.cs
- AsyncCompletedEventArgs.cs
- Visual3D.cs
- MailMessage.cs
- OleCmdHelper.cs
- IItemProperties.cs
- Effect.cs
- CodeArrayIndexerExpression.cs
- TrackingSection.cs
- WmpBitmapEncoder.cs
- WaitForChangedResult.cs
- NetPeerTcpBinding.cs
- PrintDialog.cs
- ProtocolProfile.cs
- AdRotator.cs
- MsmqProcessProtocolHandler.cs
- Point3DValueSerializer.cs
- Emitter.cs
- HtmlToClrEventProxy.cs
- HostingEnvironmentSection.cs
- ContextProperty.cs
- EntityDataSourceChangedEventArgs.cs
- TextRangeEditLists.cs
- CodeAssignStatement.cs
- SystemFonts.cs
- DockPanel.cs
- XmlSchemaSimpleContentRestriction.cs
- HttpListenerContext.cs
- XmlQueryTypeFactory.cs
- TextSegment.cs
- HtmlTernaryTree.cs
- WebBrowser.cs
- ConnectorSelectionGlyph.cs
- SqlConnectionFactory.cs
- DataControlReferenceCollection.cs
- NativeMethods.cs
- CryptoConfig.cs
- MessageAction.cs
- Int16.cs
- ColorConvertedBitmapExtension.cs
- OAVariantLib.cs
- CounterSample.cs
- QilTernary.cs
- FormClosedEvent.cs
- DesignerAutoFormatCollection.cs
- MarginCollapsingState.cs
- storepermissionattribute.cs
- IDictionary.cs
- PasswordTextContainer.cs
- QuaternionAnimation.cs
- SystemUdpStatistics.cs
- MapPathBasedVirtualPathProvider.cs
- Debug.cs
- UnsafeNativeMethods.cs
- ReadOnlyTernaryTree.cs
- DesignerProperties.cs
- CacheManager.cs
- SQLByte.cs
- X509Chain.cs
- linebase.cs
- HybridCollection.cs
- UdpConstants.cs
- FactoryGenerator.cs
- TransformCollection.cs
- GenericParameterDataContract.cs
- TextTreeUndo.cs