Reset() public method

public Reset ( ) : void
return void
Exemplo n.º 1
0
 public void Reset()
 {
     mStatus     = -1;
     Error       = null;
     IsCompleted = false;
     Result      = null;
     mSpinWait.Reset();
     mResetEvent.Reset();
 }
Exemplo n.º 2
0
        // 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();
                }
            }
        }
Exemplo n.º 4
0
 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);
 }
Exemplo n.º 5
0
        /// <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;

        }
Exemplo n.º 6
0
        /// <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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        /// <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();
                }

            }
        }
Exemplo n.º 9
0
        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;
 }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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);
            }
        }
Exemplo n.º 13
0
        /// <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;

        }
Exemplo n.º 14
0
        /// <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();
        }