public void Reset() { mStatus = -1; Error = null; IsCompleted = false; Result = null; mSpinWait.Reset(); mResetEvent.Reset(); }
// Helper function to send an entire test sequence fast (no RX, no open/close of serial) //public void Send_test_sequence_fast(byte[] tx_buf, SerialPort fpga_com_port) //{ // Open Serial Port //SerialPort fpga_com_port = setup_serial_port(); // Send Data //Send_serial_data_turbo(tx_buf, fpga_com_port); // Rx Reply //string rx_string = Read_serial_data(fpga_com_port); // Print //Debug.WriteLine("Write: 0x" + tx_string); //Debug.WriteLine("Read: 0x" + rx_string); //Debug.WriteLine("Data Equal: " + tx_string.Equals(rx_string)); // Close Serial Port //close_serial_port(fpga_com_port); //} // Helper function allow us to sleep with microsecond resolution but burns through CPU clock cycles as spin-locks rather than sleeps // Needs this as Windows scheduler only works at the 13ms resolution // This function shall allow us to specify a microsecond and achieve timing with max error of about 30 uS overshoot (worst-case seen in practice) // Perfect for our application where we want timing accurate to about 0.1mS public void high_resolution_sleep_us(UInt32 wait_time_in_microseconds) { //// Make sure we are using the High Performance Stopwatch //if (Stopwatch.IsHighResolution) //{ // Console.WriteLine("Operations timed using the system's high-resolution performance counter."); //} //else //{ // Console.WriteLine("Operations timed using the DateTime class."); //} // Where we are now Stopwatch my_stopwatch = Stopwatch.StartNew(); //long starting_timestamp = Stopwatch.GetTimestamp(); // Where we want to get to, we count this using ticks rather than timestamps as more precise and its how the API works long nano_sec_per_tick = (1000L * 1000L * 1000L) / Stopwatch.Frequency; // Ony my PC, observed that this was 100 nanosec/tick => Our timer has a 10 MHz tick rate, nice, plenty for microsecond resolution long ticks_to_wait = (wait_time_in_microseconds * 1000L) / nano_sec_per_tick; long starting_ticks = my_stopwatch.ElapsedTicks; long target_ticks = starting_ticks + ticks_to_wait; // Use a spin-lock structure for no-ops to get our timing - .Net way of doing this SpinWait spin_locker = new System.Threading.SpinWait(); long tick_count = my_stopwatch.ElapsedTicks; while (tick_count < target_ticks) { // Spin-Lock until we have reached our tips target tick_count = my_stopwatch.ElapsedTicks; spin_locker.SpinOnce(); // Want't good timing, so reset spin_locker before it goes into a longer sleep if (spin_locker.NextSpinWillYield) { spin_locker.Reset(); } //Console.WriteLine("Ticks: " + tick_count); } //spin_locker( )1 // Now check how long it took for debugging long ending_ticks = my_stopwatch.ElapsedTicks; long elapsed_ticks = ending_ticks - starting_ticks; //double ElapsedSeconds = elapsed_ticks * (1.0 / Stopwatch.Frequency); double ElapsedMicroSeconds = elapsed_ticks * (nano_sec_per_tick / 1000.0); // ORdered like this to not lose precision due to truncations //Console.WriteLine("Elapsed Microseconds: " + ElapsedMicroSeconds); }
protected override void ConsumeItems( int count ) { SpinWait spinWait = new SpinWait(); int value; for ( int i = 0; i < count; ) { if ( this.stack.TryPop( out value ) ) { i++; spinWait.Reset(); } else { spinWait.SpinOnce(); } } }
private bool do_Process(ConcurrentQueue <T> mq, int x) { spin.Reset(); while (!mq.IsEmpty) { T msg; while (mq.TryPeek(out msg)) { IsProcessSuccess = true; try { messageArg.Message = msg; OnMessageComing(messageArg); } finally { if (IsProcessSuccess) { tryCount = 0; mq.TryDequeue(out msg); } else { tryCount++; if (tryCount >= MaxTryCount) { tryCount = 0; mq.TryDequeue(out msg); } } } if (spin.Count >= SpinRate * x) { return(false); } spin.SpinOnce(); } } return(false); }
/// <summary> /// Signals that a participant has reached the barrier and waits for all other participants to reach /// the barrier as well, using a /// 32-bit signed integer to measure the time interval, while observing a <see /// cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to /// observe.</param> /// <returns>true if all other participants reached the barrier; otherwise, false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a /// negative number other than -1, which represents an infinite time-out.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action, the barrier currently has 0 participants, /// or the barrier is being used by more threads than are registered as participants. /// </exception> /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been /// canceled.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new System.ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, SR.GetString(SR.Barrier_SignalAndWait_ArgumentOutOfRange)); } // in case of this is called from the PHA if (m_actionCallerID != 0 && Thread.CurrentThread.ManagedThreadId == m_actionCallerID) { throw new InvalidOperationException(SR.GetString(SR.Barrier_InvalidOperation_CalledFromPHA)); } // local variables to extract the basic barrier variable and update them // The are declared here instead of inside the loop body because the will be used outside the loop bool sense; // The sense of the barrier *before* the phase associated with this SignalAndWait call completes int total; int current; int currentTotal; long phase; SpinWait spinner = new SpinWait(); while (true) { currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out sense); phase = CurrentPhaseNumber; // throw if zero participants if (total == 0) { throw new InvalidOperationException(SR.GetString(SR.Barrier_SignalAndWait_InvalidOperation_ZeroTotal)); } // Try to detect if the number of threads for this phase exceeded the total number of participants or not // This can be detected if the current is zero which means all participants for that phase has arrived and the phase number is not changed yet if (current == 0 && sense != (CurrentPhaseNumber % 2 == 0)) { throw new InvalidOperationException(SR.GetString(SR.Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded)); } //This is the last thread, finish the phase if (current + 1 == total) { if (SetCurrentTotal(currentTotal, 0, total, !sense)) { #if !FEATURE_PAL && !SILVERLIGHT // PAL doesn't support eventing if (CdsSyncEtwBCLProvider.Log.IsEnabled()) { CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(sense, CurrentPhaseNumber); } #endif FinishPhase(sense); return true; } } else if (SetCurrentTotal(currentTotal, current + 1, total, sense)) { break; } spinner.SpinOnce(); } // ** Perform the real wait ** // select the correct event to wait on, based on the current sense. ManualResetEventSlim eventToWaitOn = (sense) ? m_evenEvent : m_oddEvent; bool waitWasCanceled = false; bool waitResult = false; try { waitResult = DiscontinuousWait(eventToWaitOn, millisecondsTimeout, cancellationToken, phase); } catch (OperationCanceledException ) { waitWasCanceled = true; } catch (ObjectDisposedException)// in case a ---- happen where one of the thread returned from SignalAndWait and the current thread calls Wait on a disposed event { // make sure the current phase for this thread is already finished, otherwise propagate the exception if (phase < CurrentPhaseNumber) waitResult = true; else throw; } if (!waitResult) { //reset the spinLock to prepare it for the next loop spinner.Reset(); //If the wait timeout expired and all other thread didn't reach the barrier yet, update the current count back while (true) { bool newSense; currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out newSense); // If the timeout expired and the phase has just finished, return true and this is considered as succeeded SignalAndWait //otherwise the timeout expired and the current phase has not been finished yet, return false //The phase is finished if the phase member variable is changed (incremented) or the sense has been changed // we have to use the statements in the comparison below for two cases: // 1- The sense is changed but the last thread didn't update the phase yet // 2- The phase is already incremented but the sense flipped twice due to the termination of the next phase if (phase < CurrentPhaseNumber || sense != newSense) { // The current phase has been finished, but we shouldn't return before the events are set/reset otherwise this thread could start // next phase and the appropriate event has not reset yet which could make it return immediately from the next phase SignalAndWait // before waiting other threads WaitCurrentPhase(eventToWaitOn, phase); Debug.Assert(phase < CurrentPhaseNumber); break; } //The phase has not been finished yet, try to update the current count. if (SetCurrentTotal(currentTotal, current - 1, total, sense)) { //if here, then the attempt to backout was successful. //throw (a fresh) oce if cancellation woke the wait //or return false if it was the timeout that woke the wait. // if (waitWasCanceled) throw new OperationCanceledException(SR.GetString(SR.Common_OperationCanceled), cancellationToken); else return false; } spinner.SpinOnce(); } } if (m_exception != null) throw new BarrierPostPhaseException(m_exception); return true; }
/// <summary> /// Signals that a participant has reached the barrier and waits for all other participants to reach /// the barrier as well, using a /// 32-bit signed integer to measure the time interval, while observing a <see /// cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to /// observe.</param> /// <returns>true if all other participants reached the barrier; otherwise, false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a /// negative number other than -1, which represents an infinite time-out.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action, the barrier currently has 0 participants, /// or the barrier is being used by more threads than are registered as participants. /// </exception> /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been /// canceled.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new System.ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, "Barrier_SignalAndWait_ArgumentOutOfRange"); } // in case of this is called from the PHA if (m_actionCallerID != 0 && Thread.CurrentThread.ManagedThreadId == m_actionCallerID) { throw new InvalidOperationException("Barrier_InvalidOperation_CalledFromPHA"); } // local variables to extract the basic barrier variable and update them // The are declared here instead of inside the loop body because the will be used outside the loop bool sense; int total; int current; int currentTotal; SpinWait spinner = new SpinWait(); while (true) { currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out sense); // throw if zero participants if (total == 0) { throw new InvalidOperationException("Barrier_SignalAndWait_InvalidOperation_ZeroTotal"); } // Try to detect if the number of threads for this phase exceeded the total number of participants or not // This can be detected if the current is zero which means all participants for that phase has arrived and the phase number is not changed yet if (current == 0 && sense != (m_currentPhase % 2 == 0)) { throw new InvalidOperationException("Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded"); } //This is the last thread, finish the phase if (current + 1 == total) { if (SetCurrentTotal(currentTotal, 0, total, !sense)) { #if !FEATURE_PAL // PAL doesn't support eventing if (CdsSyncEtwBCLProvider.Log.IsEnabled()) { CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(sense, m_currentPhase); } #endif FinishPhase(sense); return(true); } } else if (SetCurrentTotal(currentTotal, current + 1, total, sense)) { break; } spinner.SpinOnce(); } // save the phase locally long phase = m_currentPhase; // ** Perform the real wait ** // select the correct event to wait on, based on the current sense. ManualResetEventSlim eventToWaitOn = (sense) ? m_evenEvent : m_oddEvent; bool waitWasCanceled = false; bool waitResult = false; try { waitResult = eventToWaitOn.Wait(millisecondsTimeout, cancellationToken); } catch (OperationCanceledException) { waitWasCanceled = true; } if (!waitResult) { //reset the spinLock to prepare it for the next loop spinner.Reset(); //If the wait timeout expired and all other thread didn't reach the barrier yet, update the current count back while (true) { bool newSense; currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out newSense); // If the timeout expired and the phase has just finished, return true and this is considered as succeeded SignalAndWait //otherwise the timeout expired and the current phase has not been finished yet, return false //The phase is finished if the phase member variable is changed (incremented) or the sense has been changed if (phase != m_currentPhase || sense != newSense) { // The current phase has been finished, but we shouldn't return before the events are set/reset otherwise this thread could start // next phase and the appropriate event has not reset yet which could make it return immediately from the next phase SignalAndWait // before waiting other threads eventToWaitOn.Wait(); Debug.Assert(phase < m_currentPhase); // assert that the phase has been completely finished //if here, then all the other participants had reached the barrier and moved to the //next phase. Hence we cannot (and should not) backout the signal and can return true. break; } //The phase has not been finished yet, try to update the current count. if (SetCurrentTotal(currentTotal, current - 1, total, sense)) { //if here, then the attempt to backout was successful. //throw (a fresh) oce if cancellation woke the wait //or return false if it was the timeout that woke the wait. // if (waitWasCanceled) { #if PFX_LEGACY_3_5 throw new OperationCanceledException2("Common_OperationCanceled", cancellationToken); #else throw new OperationCanceledException("Common_OperationCanceled", cancellationToken); #endif } else { return(false); } } spinner.SpinOnce(); } } if (m_exception != null) { throw new BarrierPostPhaseException(m_exception); } return(true); }
/// <summary> /// Signals that a participant has reached the barrier and waits for all other participants to reach /// the barrier as well, using a /// 32-bit signed integer to measure the time interval, while observing a <see /// cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to /// observe.</param> /// <returns>true if all other participants reached the barrier; otherwise, false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a /// negative number other than -1, which represents an infinite time-out.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action, the barrier currently has 0 participants, /// or the barrier is being used by more threads than are registered as participants. /// </exception> /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been /// canceled.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException2(nameof(millisecondsTimeout), millisecondsTimeout, SR.Barrier_SignalAndWait_ArgumentOutOfRange); } // in case of this is called from the PHA if (_actionCallerID != 0 && Environment2.CurrentManagedThreadId == _actionCallerID) { throw new InvalidOperationException(SR.Barrier_InvalidOperation_CalledFromPHA); } // local variables to extract the basic barrier variable and update them // The are declared here instead of inside the loop body because the will be used outside the loop bool sense; // The sense of the barrier *before* the phase associated with this SignalAndWait call completes int total; int current; int currentTotal; long phase; SpinWait spinner = new SpinWait(); while (true) { currentTotal = _currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out sense); phase = CurrentPhaseNumber; // throw if zero participants if (total == 0) { throw new InvalidOperationException(SR.Barrier_SignalAndWait_InvalidOperation_ZeroTotal); } // Try to detect if the number of threads for this phase exceeded the total number of participants or not // This can be detected if the current is zero which means all participants for that phase has arrived and the phase number is not changed yet if (current == 0 && sense != (CurrentPhaseNumber % 2 == 0)) { throw new InvalidOperationException(SR.Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded); } //This is the last thread, finish the phase if (current + 1 == total) { if (SetCurrentTotal(currentTotal, 0, total, !sense)) { //if (CdsSyncEtwBCLProvider.Log.IsEnabled()) //{ // CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(sense, CurrentPhaseNumber); //} FinishPhase(sense); return(true); } } else if (SetCurrentTotal(currentTotal, current + 1, total, sense)) { break; } spinner.SpinOnce(); } // ** Perform the real wait ** // select the correct event to wait on, based on the current sense. ManualResetEventSlim eventToWaitOn = (sense) ? _evenEvent : _oddEvent; bool waitWasCanceled = false; bool waitResult = false; try { waitResult = DiscontinuousWait(eventToWaitOn, millisecondsTimeout, cancellationToken, phase); } catch (OperationCanceledException) { waitWasCanceled = true; } catch (ObjectDisposedException)// in case a race happen where one of the thread returned from SignalAndWait and the current thread calls Wait on a disposed event { // make sure the current phase for this thread is already finished, otherwise propagate the exception if (phase < CurrentPhaseNumber) { waitResult = true; } else { throw; } } if (!waitResult) { //reset the spinLock to prepare it for the next loop spinner.Reset(); //If the wait timeout expired and all other thread didn't reach the barrier yet, update the current count back while (true) { bool newSense; currentTotal = _currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out newSense); // If the timeout expired and the phase has just finished, return true and this is considered as succeeded SignalAndWait //otherwise the timeout expired and the current phase has not been finished yet, return false //The phase is finished if the phase member variable is changed (incremented) or the sense has been changed // we have to use the statements in the comparison below for two cases: // 1- The sense is changed but the last thread didn't update the phase yet // 2- The phase is already incremented but the sense flipped twice due to the termination of the next phase if (phase < CurrentPhaseNumber || sense != newSense) { // The current phase has been finished, but we shouldn't return before the events are set/reset otherwise this thread could start // next phase and the appropriate event has not reset yet which could make it return immediately from the next phase SignalAndWait // before waiting other threads WaitCurrentPhase(eventToWaitOn, phase); Debug.Assert(phase < CurrentPhaseNumber); break; } //The phase has not been finished yet, try to update the current count. if (SetCurrentTotal(currentTotal, current - 1, total, sense)) { //if here, then the attempt to back out was successful. //throw (a fresh) OCE if cancellation woke the wait //or return false if it was the timeout that woke the wait. // if (waitWasCanceled) { throw new InternalOCE(SR.Common_OperationCanceled, cancellationToken); } else { return(false); } } spinner.SpinOnce(); } } if (_exception != null) { throw new BarrierPostPhaseException(_exception); } return(true); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> private void InternalDispose() { if(Interlocked.CompareExchange(ref isClosed,1,0) == 0) { //closing = true; if (LOG.IsDebugEnabled) LOG.DebugFormat("Closing client for session: 0x{0:X}", SessionId); try { SubmitRequest(new RequestHeader { Type = (int)OpCode.CloseSession }, null, null, null); SpinWait spin = new SpinWait(); DateTime timeoutAt = DateTime.UtcNow.Add(SessionTimeout); while (!producer.IsConnectionClosedByServer) { spin.SpinOnce(); if (spin.Count > MaximumSpin) { if (timeoutAt <= DateTime.UtcNow) { throw new TimeoutException( string.Format("Timed out in Dispose() while closing session: 0x{0:X}", SessionId)); } spin.Reset(); } } } catch (ThreadInterruptedException) { // ignore, close the send/event threads } catch (Exception ex) { LOG.WarnFormat("Error disposing {0} : {1}", this.GetType().FullName, ex.Message); } finally { producer.Dispose(); consumer.Dispose(); } } }
public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { bool flag; int num; int num2; int currentTotalCount; this.ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, SR.GetString("Barrier_SignalAndWait_ArgumentOutOfRange")); } if ((this.m_actionCallerID != 0) && (Thread.CurrentThread.ManagedThreadId == this.m_actionCallerID)) { throw new InvalidOperationException(SR.GetString("Barrier_InvalidOperation_CalledFromPHA")); } SpinWait wait = new SpinWait(); while (true) { currentTotalCount = this.m_currentTotalCount; this.GetCurrentTotal(currentTotalCount, out num2, out num, out flag); if (num == 0) { throw new InvalidOperationException(SR.GetString("Barrier_SignalAndWait_InvalidOperation_ZeroTotal")); } if ((num2 == 0) && (flag != ((this.m_currentPhase % 2L) == 0L))) { throw new InvalidOperationException(SR.GetString("Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded")); } if ((num2 + 1) == num) { if (this.SetCurrentTotal(currentTotalCount, 0, num, !flag)) { if (CdsSyncEtwBCLProvider.Log.IsEnabled()) { CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(flag, this.m_currentPhase); } this.FinishPhase(flag); return(true); } } else if (this.SetCurrentTotal(currentTotalCount, num2 + 1, num, flag)) { break; } wait.SpinOnce(); } long currentPhase = this.m_currentPhase; ManualResetEventSlim slim = flag ? this.m_evenEvent : this.m_oddEvent; bool flag2 = false; bool flag3 = false; try { flag3 = slim.Wait(millisecondsTimeout, cancellationToken); } catch (OperationCanceledException) { flag2 = true; } if (!flag3) { wait.Reset(); while (true) { bool flag4; currentTotalCount = this.m_currentTotalCount; this.GetCurrentTotal(currentTotalCount, out num2, out num, out flag4); if ((currentPhase != this.m_currentPhase) || (flag != flag4)) { slim.Wait(); break; } if (this.SetCurrentTotal(currentTotalCount, num2 - 1, num, flag)) { if (flag2) { throw new OperationCanceledException(SR.GetString("Common_OperationCanceled"), cancellationToken); } return(false); } wait.SpinOnce(); } } if (this.m_exception != null) { throw new BarrierPostPhaseException(this.m_exception); } return(true); }
public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { bool flag; int num; int num2; int currentTotalCount; this.ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, SR.GetString("Barrier_SignalAndWait_ArgumentOutOfRange")); } if ((this.m_actionCallerID != 0) && (Thread.CurrentThread.ManagedThreadId == this.m_actionCallerID)) { throw new InvalidOperationException(SR.GetString("Barrier_InvalidOperation_CalledFromPHA")); } SpinWait wait = new SpinWait(); while (true) { currentTotalCount = this.m_currentTotalCount; this.GetCurrentTotal(currentTotalCount, out num2, out num, out flag); if (num == 0) { throw new InvalidOperationException(SR.GetString("Barrier_SignalAndWait_InvalidOperation_ZeroTotal")); } if ((num2 == 0) && (flag != ((this.m_currentPhase % 2L) == 0L))) { throw new InvalidOperationException(SR.GetString("Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded")); } if ((num2 + 1) == num) { if (this.SetCurrentTotal(currentTotalCount, 0, num, !flag)) { if (CdsSyncEtwBCLProvider.Log.IsEnabled()) { CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(flag, this.m_currentPhase); } this.FinishPhase(flag); return true; } } else if (this.SetCurrentTotal(currentTotalCount, num2 + 1, num, flag)) { break; } wait.SpinOnce(); } long currentPhase = this.m_currentPhase; ManualResetEventSlim slim = flag ? this.m_evenEvent : this.m_oddEvent; bool flag2 = false; bool flag3 = false; try { flag3 = slim.Wait(millisecondsTimeout, cancellationToken); } catch (OperationCanceledException) { flag2 = true; } if (!flag3) { wait.Reset(); while (true) { bool flag4; currentTotalCount = this.m_currentTotalCount; this.GetCurrentTotal(currentTotalCount, out num2, out num, out flag4); if ((currentPhase != this.m_currentPhase) || (flag != flag4)) { slim.Wait(); break; } if (this.SetCurrentTotal(currentTotalCount, num2 - 1, num, flag)) { if (flag2) { throw new OperationCanceledException(SR.GetString("Common_OperationCanceled"), cancellationToken); } return false; } wait.SpinOnce(); } } if (this.m_exception != null) { throw new BarrierPostPhaseException(this.m_exception); } return true; }
public void PwmProc() { // totalCycle = (1/n)*1000 = Total MS for the full cycle // onCycle = totalCycle * (DutyCycle / 100) // offCycle = totalCycle - onCycle; SpinWait sp = new SpinWait(); Stopwatch sw = new Stopwatch(); int totalCycleTicks = (int)((1f / Frequency) * Stopwatch.Frequency); int onTicks = (int)Math.Round(totalCycleTicks * (DutyCycle / 100f)); int offTicks = totalCycleTicks - onTicks; Debug.WriteLine("On Ticks: " + onTicks); while (IsRunning) { /**** ON ****/ // Turn the pin on for the duty cycle Pin(true); // Let the pin stay high until we stop or sw.Reset(); sp.Reset(); sw.Start(); while (sw.ElapsedTicks < onTicks) ; //sp.SpinOnce(); //Debug.WriteLine("Total Spin On: " + sw.ElapsedTicks + " and needed " + onTicks); /**** OFF ****/ // Turn the pin off for the rest period Pin(false); sw.Reset(); sp.Reset(); sw.Start(); while (sw.ElapsedTicks < offTicks) ; //sp.SpinOnce(); //Debug.WriteLine("Total Spin Off: " + sw.ElapsedTicks + " and needed " + offTicks); } // Turn off the PIN when we're done Pin(false); }
protected void OnRunning() { SpinWait wait = new SpinWait(); while (true) { int state = m_state; if (state == State.ScheduledToRun && Interlocked.CompareExchange(ref m_state, State.Running, State.ScheduledToRun) == State.ScheduledToRun) break; if (state == State.ScheduledToRunAfterDelay && Interlocked.CompareExchange(ref m_state, State.Running, State.ScheduledToRunAfterDelay) == State.ScheduledToRunAfterDelay) break; wait.SpinOnce(); } wait.Reset(); m_runAgain = false; m_runAgainAfterDelay = -1; Thread.MemoryBarrier(); m_args.StartDisposalCallSuccessful = m_startDisposalCallSuccessful; bool failedRun = !m_callback.TryInvoke(m_args); if (m_args.ShouldDispose || failedRun) { InternalDispose_FromWorkerThread(); Interlocked.Exchange(ref m_state, State.Disposed); return; } Interlocked.Exchange(ref m_state, State.AfterRunning); //Notifies that the RunAgain and RunAgainAfterDelay variables are going to be used // to make decisions. Therefore, if setting these variables after this point, modifying the state machine will be // necessary if (m_runAgain) { Interlocked.Exchange(ref m_state, State.ScheduledToRun); InternalStart_FromWorkerThread(); } else if (m_runAgainAfterDelay >= 0) { InternalStart_FromWorkerThread(m_runAgainAfterDelay); Interlocked.Exchange(ref m_state, State.ScheduledToRunAfterDelay); } else { InternalDoNothing_FromWorkerThread(); Interlocked.Exchange(ref m_state, State.NotRunning); } }
/// <summary> /// Signals that a participant has reached the barrier and waits for all other participants to reach /// the barrier as well, using a /// 32-bit signed integer to measure the time interval, while observing a <see /// cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to /// observe.</param> /// <returns>true if all other participants reached the barrier; otherwise, false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a /// negative number other than -1, which represents an infinite time-out.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action, the barrier currently has 0 participants, /// or the barrier is being used by more threads than are registered as participants. /// </exception> /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been /// canceled.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, "The specified timeout must represent a value between -1 and Int32.MaxValue, inclusive."); } // in case of this is called from the PHA if (_actionCallerId != 0 && Thread.CurrentThread.ManagedThreadId == _actionCallerId) { throw new InvalidOperationException("This method may not be called from within the postPhaseAction."); } // local variables to extract the basic barrier variable and update them // The are declared here instead of inside the loop body because the will be used outside the loop bool sense; // The sense of the barrier *before* the phase associated with this SignalAndWait call completes int total; int current; int currentTotal; long phase; var spinner = new SpinWait(); while (true) { currentTotal = Thread.VolatileRead(ref _currentTotalCount); GetCurrentTotal(currentTotal, out current, out total, out sense); phase = CurrentPhaseNumber; // throw if zero participants if (total == 0) { throw new InvalidOperationException("The barrier has no registered participants."); } // Try to detect if the number of threads for this phase exceeded the total number of participants or not // This can be detected if the current is zero which means all participants for that phase has arrived and the phase number is not changed yet if (current == 0 && sense != (CurrentPhaseNumber % 2 == 0)) { throw new InvalidOperationException("The number of threads using the barrier exceeded the total number of registered participants."); } //This is the last thread, finish the phase if (current + 1 == total) { if (SetCurrentTotal(currentTotal, 0, total, !sense)) { FinishPhase(sense); return true; } } else if (SetCurrentTotal(currentTotal, current + 1, total, sense)) { break; } spinner.SpinOnce(); } // ** Perform the real wait ** // select the correct event to wait on, based on the current sense. var eventToWaitOn = (sense) ? _evenEvent : _oddEvent; var waitWasCanceled = false; var waitResult = false; try { waitResult = DiscontinuousWait(eventToWaitOn, millisecondsTimeout, cancellationToken, phase); } catch (OperationCanceledException) { waitWasCanceled = true; } catch (ObjectDisposedException)// in case a ---- happen where one of the thread returned from SignalAndWait and the current thread calls Wait on a disposed event { // make sure the current phase for this thread is already finished, otherwise propagate the exception if (phase < CurrentPhaseNumber) waitResult = true; else throw; } if (!waitResult) { //reset the spinLock to prepare it for the next loop spinner.Reset(); //If the wait timeout expired and all other thread didn't reach the barrier yet, update the current count back while (true) { bool newSense; currentTotal = Thread.VolatileRead(ref _currentTotalCount); GetCurrentTotal(currentTotal, out current, out total, out newSense); // If the timeout expired and the phase has just finished, return true and this is considered as succeeded SignalAndWait //otherwise the timeout expired and the current phase has not been finished yet, return false //The phase is finished if the phase member variable is changed (incremented) or the sense has been changed // we have to use the statements in the comparison below for two cases: // 1- The sense is changed but the last thread didn't update the phase yet // 2- The phase is already incremented but the sense flipped twice due to the termination of the next phase if (phase < CurrentPhaseNumber || sense != newSense) { // The current phase has been finished, but we shouldn't return before the events are set/reset otherwise this thread could start // next phase and the appropriate event has not reset yet which could make it return immediately from the next phase SignalAndWait // before waiting other threads WaitCurrentPhase(eventToWaitOn, phase); Debug.Assert(phase < CurrentPhaseNumber); break; } //The phase has not been finished yet, try to update the current count. if (SetCurrentTotal(currentTotal, current - 1, total, sense)) { //if here, then the attempt to backout was successful. //throw (a fresh) oce if cancellation woke the wait //or return false if it was the timeout that woke the wait. // if (waitWasCanceled) throw new NewOperationCanceledException("The operation was canceled.", cancellationToken); else return false; } spinner.SpinOnce(); } } if (_exception != null) throw new BarrierPostPhaseException(_exception); return true; }
/// <summary> /// Signals that a participant has reached the barrier and waits for all other participants to reach /// the barrier as well, using a /// 32-bit signed integer to measure the time interval, while observing a <see /// cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to /// observe.</param> /// <returns>true if all other participants reached the barrier; otherwise, false.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a /// negative number other than -1, which represents an infinite time-out.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action, the barrier currently has 0 participants, /// or the barrier is being used by more threads than are registered as participants. /// </exception> /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been /// canceled.</exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public bool SignalAndWait(int millisecondsTimeout, CancellationToken cancellationToken) { ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (millisecondsTimeout < -1) { throw new System.ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, "Barrier_SignalAndWait_ArgumentOutOfRange"); } // in case of this is called from the PHA if (m_actionCallerID != 0 && Thread.CurrentThread.ManagedThreadId == m_actionCallerID) { throw new InvalidOperationException("Barrier_InvalidOperation_CalledFromPHA"); } // local variables to extract the basic barrier variable and update them // The are declared here instead of inside the loop body because the will be used outside the loop bool sense; int total; int current; int currentTotal; SpinWait spinner = new SpinWait(); while (true) { currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out sense); // throw if zero participants if (total == 0) { throw new InvalidOperationException("Barrier_SignalAndWait_InvalidOperation_ZeroTotal"); } // Try to detect if the number of threads for this phase exceeded the total number of participants or not // This can be detected if the current is zero which means all participants for that phase has arrived and the phase number is not changed yet if (current == 0 && sense != (m_currentPhase % 2 == 0)) { throw new InvalidOperationException("Barrier_SignalAndWait_InvalidOperation_ThreadsExceeded"); } //This is the last thread, finish the phase if (current + 1 == total) { if (SetCurrentTotal(currentTotal, 0, total, !sense)) { #if !FEATURE_PAL // PAL doesn't support eventing if (CdsSyncEtwBCLProvider.Log.IsEnabled()) { CdsSyncEtwBCLProvider.Log.Barrier_PhaseFinished(sense, m_currentPhase); } #endif FinishPhase(sense); return true; } } else if (SetCurrentTotal(currentTotal, current + 1, total, sense)) { break; } spinner.SpinOnce(); } // save the phase locally long phase = m_currentPhase; // ** Perform the real wait ** // select the correct event to wait on, based on the current sense. ManualResetEventSlim eventToWaitOn = (sense) ? m_evenEvent : m_oddEvent; bool waitWasCanceled = false; bool waitResult = false; try { waitResult = eventToWaitOn.Wait(millisecondsTimeout, cancellationToken); } catch (OperationCanceledException ) { waitWasCanceled = true; } if (!waitResult) { //reset the spinLock to prepare it for the next loop spinner.Reset(); //If the wait timeout expired and all other thread didn't reach the barrier yet, update the current count back while (true) { bool newSense; currentTotal = m_currentTotalCount; GetCurrentTotal(currentTotal, out current, out total, out newSense); // If the timeout expired and the phase has just finished, return true and this is considered as succeeded SignalAndWait //otherwise the timeout expired and the current phase has not been finished yet, return false //The phase is finished if the phase member variable is changed (incremented) or the sense has been changed if (phase != m_currentPhase || sense != newSense) { // The current phase has been finished, but we shouldn't return before the events are set/reset otherwise this thread could start // next phase and the appropriate event has not reset yet which could make it return immediately from the next phase SignalAndWait // before waiting other threads eventToWaitOn.Wait(); Debug.Assert(phase < m_currentPhase); // assert that the phase has been completely finished //if here, then all the other participants had reached the barrier and moved to the //next phase. Hence we cannot (and should not) backout the signal and can return true. break; } //The phase has not been finished yet, try to update the current count. if (SetCurrentTotal(currentTotal, current - 1, total, sense)) { //if here, then the attempt to backout was successful. //throw (a fresh) oce if cancellation woke the wait //or return false if it was the timeout that woke the wait. // if (waitWasCanceled) { #if PFX_LEGACY_3_5 throw new OperationCanceledException2("Common_OperationCanceled", cancellationToken); #else throw new OperationCanceledException("Common_OperationCanceled", cancellationToken); #endif } else return false; } spinner.SpinOnce(); } } if (m_exception != null) throw new BarrierPostPhaseException(m_exception); return true; }
/// <summary> /// Wait for MD5 calculation to be finished. /// In our test, MD5 calculation is really fast, /// and SpinOnce has sleep mechanism, so use Spin instead of sleep here. /// </summary> private void WaitMD5CalculationToFinish() { if (this.finishedSeparateMd5Calculator) { return; } SpinWait sw = new SpinWait(); while (!this.finishedSeparateMd5Calculator) { sw.SpinOnce(); } sw.Reset(); }