private void Run()
            {
                int fail = 0;

                StWaitable[] ws = new StWaitable[] { s };
                VConsole.WriteLine("+++ a #{0} started...", id);
                do
                {
                    try {
                        while (!s.Wait(1, new StCancelArgs((id & 1) + 1, shutdown)))
                        {
                            //while (!s.Wait(new StCancelArgs((n & 1) + 1, shutdown))) {
                            //while (StWaitable.WaitAny(ws, new StCancelArgs((n & 1) + 1, shutdown)) == StParkStatus.Timeout) {
                            //while (!StWaitable.WaitAll(ws, new StCancelArgs((n & 1) + 10, shutdown))) {
                            if (shutdown.IsSet)
                            {
                                goto Exit;
                            }
                            fail++;
                            //Thread.Sleep(0);
                        }
                    } catch (StThreadAlertedException) {
                        break;
                    }
                    if ((++acquires[id] % 20000) == 0)
                    {
                        VConsole.Write("-{0}", id);
                    }
                } while (!shutdown.IsSet);
Exit:
                VConsole.WriteLine("+++ acquirer #{0} exiting: [{1}/{2}]",
                                   id, acquires[id], fail);
                done.Signal();
            }
Exemplo n.º 2
0
            private void Run()
            {
                VConsole.WriteLine("+++ a #{0} started...", id);
                int fail = 0;

                do
                {
                    try {
                        int index = StWaitable.WaitAny(es, new StCancelArgs(1, shutdown));
                        if (index >= 0 && index < es.Length)
                        {
                            if ((++acquires[id] % 20000) == 0)
                            {
                                VConsole.Write("-{0}", id);
                            }
                        }
                        else
                        {
                            fail++;
                        }
                    } catch (StThreadAlertedException) {
                        break;
                    }
                } while (true);
                VConsole.WriteLine("+++ a #{0} exiting: [{1}/{2}]",
                                   id, acquires[id], fail);
                done.Signal();
            }
        public static void GlobalThread(int id, bool waitAll)
        {
            int fail  = 0;
            int count = 0;

            try {
                do
                {
                    if (waitAll ? StWaitable.WaitAll(evts, new StCancelArgs(shutdown))
                                : StWaitable.WaitAny(evts, new StCancelArgs(id, shutdown)) != StParkStatus.Timeout)
                    {
                        count++;
                    }
                    else
                    {
                        fail++;
                    }
                } while (!shutdown.IsSet);
            }
            catch (StThreadAlertedException) { }

            VConsole.WriteLine("+++ {0} (Wait{1}) exiting: {2}/{3}",
                               Thread.CurrentThread.Name, waitAll ? "All" : "Any", count, fail);
            done.Signal();
        }
Exemplo n.º 4
0
            private void Run()
            {
                VConsole.WriteLine("+++ a #{0} started...", id);
                int fail = 0;
                int index;

                do
                {
                    try {
                        index = StWaitable.WaitAny(ss, new StCancelArgs(1, shutdown));
                        if (index >= 0 && index < SEMAPHORES)
                        {
                            if ((++acquires[id] % 500) == 0)
                            {
                                VConsole.Write("-{0}", id);
                            }
                        }
                        else
                        {
                            fail++;
                        }
                    } catch (StThreadAlertedException) {
                        break;
                    }
                    //Thread.Sleep(0);
                } while (!shutdown.IsSet);
                VConsole.WriteLine("+++ a #{0} exiting, [{1}/{2}]", id, acquires[id], fail);
                done.Signal();
            }
Exemplo n.º 5
0
        //
        // Constructors.
        //

        public StTimer(bool notificationTimer) {
            if (notificationTimer) {
                tmrEvent = new StNotificationEvent();
            } else {
                tmrEvent = new StSynchronizationEvent();
            }
 
            state = INACTIVE;
            cbparker = new CbParker(TimerCallback);
            timer = new RawTimer(cbparker);        
        }
        private static void Run(int id)
        {
            int fail   = 0;
            var sem0   = new StSemaphore(0);
            var sem1   = new StSemaphore(0);
            var sem2   = new Semaphore(0, int.MaxValue);
            var sem3   = new Semaphore(0, int.MaxValue);
            var stsems = new[] { sem0, sem1 };
            var whsems = new[] { sem2, sem3 };

            VConsole.WriteLine("+++ w #{0} started...", id);
            do
            {
                ThreadPool.QueueUserWorkItem(delegate {
                    sem0.Release(1);
                    sem1.Release(1);
                    Thread.Sleep(0);
                    sem2.Release(1);
                    sem3.Release(1);
                    if (sem1.Wait(1, new StCancelArgs(0)))
                    {
                        Thread.Sleep(0);
                        sem1.Release(1);
                    }
                });

                try {
                    do
                    {
                        if (StWaitable.WaitAll(stsems, whsems, new StCancelArgs(id)))
                        {
                            break;
                        }
                        fail++;
                    } while (true);
                } catch (StThreadAlertedException) {
                    break;
                }

                if ((++counts[id] % 1000) == 0)
                {
                    VConsole.Write("-{0}", id);
                }
            } while (shutdown == 0);
            VConsole.WriteLine("+++ w #{0} exiting: [{1}/{2}]", id, counts[id], fail);
            done.Signal();
        }
        public static void RingThread(int id)
        {
            int index = id;
            int count = 0;

            StWaitable.SignalAndWait(start, evts[index]);

            try {
                do
                {
                    evts[index].Reset();
                    count++;
                    index = (index + 1) & (RING_THREADS - 1);
                    evts[index].Set();
                    evts[index].WaitOne(new StCancelArgs(shutdown));
                } while (!shutdown.IsSet);
            } catch (StThreadAlertedException) { }

            counts[index] = count;
            VConsole.WriteLine("+++ {0} exiting: {1}", Thread.CurrentThread.Name, count);
            done.Signal();
        }
Exemplo n.º 8
0
     //
     // WaitOne unconditionally until all the specified waitables
     // allow the acquire.
     //
 
     public static void WaitAll(StWaitable[] ws) {
         WaitAll(ws, StCancelArgs.None);
     }
 private void Run() {
     int fail = 0;
     StWaitable[] ws = new StWaitable[] { s };
     VConsole.WriteLine("+++ a #{0} started...", id);
     do {
         try {
             while (!s.Wait(1, new StCancelArgs((id & 1) + 1, shutdown))) {
                 //while (!s.Wait(new StCancelArgs((n & 1) + 1, shutdown))) {
                 //while (StWaitable.WaitAny(ws, new StCancelArgs((n & 1) + 1, shutdown)) == StParkStatus.Timeout) {
                 //while (!StWaitable.WaitAll(ws, new StCancelArgs((n & 1) + 10, shutdown))) {
                 if (shutdown.IsSet) {
                     goto Exit;
                 }
                 fail++;
                 //Thread.Sleep(0);
             }
         } catch (StThreadAlertedException) {
             break;
         }
         if ((++acquires[id] % 20000) == 0) {
             VConsole.Write("-{0}", id);
         }
     } while (!shutdown.IsSet);
 Exit:
     VConsole.WriteLine("+++ acquirer #{0} exiting: [{1}/{2}]",
                         id, acquires[id], fail);
     done.Signal();
 }
Exemplo n.º 10
0
 /// <summary>
 /// Waits unconditionally until one of the specified waitables
 /// can be acquired.
 /// </summary>
 /// <param name="ws">The array of waitables.</param>
 /// <returns></returns>
 public static int WaitAny(StWaitable[] ws) {
     return WaitAny(ws, StCancelArgs.None);
 }
Exemplo n.º 11
0
        /// <summary>
        /// Waits until one of the specified waitables or wait handles can be 
        /// acquired, activating the specified cancellers. 
        /// </summary>
        /// <param name="ws">The array of waitables.</param>
        /// <param name="hs">The array of wait handles.</param>
        /// <param name="cargs">The cancellation arguments.</param>
        /// <returns></returns>
        public static int WaitAny(StWaitable[] ws, WaitHandle[] hs, StCancelArgs cargs) {
            if (ws == null) {
                throw new ArgumentNullException("ws");
            }

            if (hs == null) {
                throw new ArgumentNullException("hs");
            }

            int len = ws.Length;

            for (int i = 0; i < hs.Length; i++) {
                if (hs[i].WaitOne(0)) {
                    return StParkStatus.Success + len + i;
                }
            }

            return WaitAnyInternal(ws, hs, cargs);
        }
Exemplo n.º 12
0
        internal static int WaitAnyInternal(StWaitable[] ws, WaitHandle[] hs, StCancelArgs cargs) {
            int len = ws.Length;

            //
            // First, we scan the *ws* array trying to acquire one of the
            // synchronizers.
            //

            for (int i = 0; i < len; i++) {
                if (ws[i]._TryAcquire()) {
                    return StParkStatus.Success + i;
                }
            }

            if (cargs.Timeout == 0) {
                return StParkStatus.Timeout;
            }

            //
            // Create a parker and execute the WaitAny prologue on all
            // waitables. We stop executing prologues as soon as we detect
            // that the acquire operation was accomplished.
            // 
             
            StParker pk = hs != null 
                        ? new StParker(EventBasedParkSpotFactory.Current.
                                       Create(new WaitAnyBehavior(hs, len)))
                        : new StParker(1);
            WaitBlock[] wbs = new WaitBlock[len];
            WaitBlock[] hints = new WaitBlock[len];

            int lv = -1;
            int sc = 0;
            int gsc = 0;
            for (int i = 0; !pk.IsLocked && i < len; i++) {
                StWaitable w = ws[i];

                if ((wbs[i] = w._WaitAnyPrologue(pk, i, ref hints[i], ref sc)) == null) {
                    if (pk.TryLock()) {
                        pk.UnparkSelf(i);
                    } else {
                        w._UndoAcquire();
                    }
                    break;
                }

                //
                // Adjust the global spin count.
                //

                if (gsc < sc) {
                    gsc = sc;
                }
                lv = i;
            }
            
            int wst = pk.Park(gsc, cargs);
            StWaitable acq = wst >= StParkStatus.Success && wst < len ? ws[wst] : null;
   
            //
            // Cancel the acquire attempt on all waitables where we executed 
            // the WaitAny prologue, except the one we acquired.
            //
        
            for (int i = 0; i <= lv; i++) {
                StWaitable w = ws[i];
                if (w != acq) {
                    w._CancelAcquire(wbs[i], hints[i]);
                }
            }

            if (wst >= StParkStatus.Success && wst < len + (hs != null ? hs.Length : 0)) {
                if (acq != null) {
                    acq._WaitEpilogue();
                }
                return wst;
            }

            StCancelArgs.ThrowIfException(wst);
            return StParkStatus.Timeout;
        }
Exemplo n.º 13
0
            private void Run()
            {
                int count  = 0;
                int failed = 0;

                Console.WriteLine("+++ ctrl #{0} starts...\n", id);
                Random rnd = new Random(Environment.TickCount * (id + 1));

                StTimer[] timers = new StTimer[TIMERS];
                for (int i = 0; i < TIMERS; i++)
                {
                    timers[i] = new StTimer(true);
                }

                do
                {
                    //
                    // Start the timers.
                    //

                    int maxTime = 0;
                    for (int i = 0; i < TIMERS; i++)
                    {
                        int delay = 100 + rnd.Next(500);
                        timers[i].Set(delay, 0, TimerCallback, timers[i]);
                        if (delay > maxTime)
                        {
                            maxTime = delay;
                        }
                    }

                    int start = Environment.TickCount;
                    try {
                        int timeout = 350 + rnd.Next(500);
                        if (StWaitable.WaitAll(timers, new StCancelArgs(timeout, shutdown)))
                        {
                            int elapsed = Environment.TickCount - start;
                            Console.WriteLine("+++ ctrl #{0}, synchronized with its timers[{1}/{2}]\n",
                                              id, maxTime, elapsed);
                            count++;
                            Thread.Sleep(100);
                            if (!shutdown.IsSet)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            int elapsed = Environment.TickCount - start;
                            Console.WriteLine("--- ctrl #{0}, timed out({1}) expired[{2}/{3}]\n",
                                              id, timeout, maxTime, elapsed);
                        }
                    } catch (StThreadAlertedException) {
                        Console.WriteLine("--- ctrl #{0}, CANCELLED\n", id);
                    }

                    //
                    // Cancel the timers.
                    //


                    for (int i = 0; i < TIMERS; i++)
                    {
                        timers[i].Cancel();
                    }
                    failed++;
                } while (!shutdown.IsSet);
                for (int i = 0; i < TIMERS; i++)
                {
                    timers[i].Cancel();
                }
                Console.WriteLine("+++ ctrl #{0} exiting after [{1}/{1}] synchs...\n",
                                  id, count, failed);
                done.Signal();
            }
Exemplo n.º 14
0
        //
        // Sorts the waitable array by the waitable id and, at the same time,
        // check if all waitables allow an immediate acquire operation.
        //
        // NOTE: The notification events are not sorted, because they don't
        //       have an acquire side-effect. The notification events are 
        //       grouped at the end of the sorted array.
        //

        private static int SortAndCheckAllowAcquire(StWaitable[] ws, StWaitable[] sws, out int nevts) {
            int i;
            StWaitable w;
            bool acqAll = true;
            int len = ws.Length;

            //
            // Find the first waitable that isn't a notification event,
            // in order to start insertion sort.
            //

            nevts = len;
            for (i = 0; i < len; i++) {
                w = ws[i];
                acqAll &= w._AllowsAcquire;

                //
                // If the current waitable is a notification event, insert
                // it at the end of the ordered array; otherwise, insert it
                // on the begin of the array and break the loop.
                //

                if (w.id == NOTIFICATION_EVENT_ID) {
                    sws[--nevts] = w;
                } else {
                    sws[0] = w;
                    break;
                }
            }

            //
            // If all synchronizers are notification events, return.
            //

            if (nevts == 0) {
                return acqAll ? 1 : 0;
            }

            //
            // Sort the remaining synchronizers using the insertion sort
            // algorithm but only with the non-notification event waitables.
            //
            
            int k = 1;
            for (i++; i < len; i++, k++) {
                w = ws[i];
                acqAll &= w._AllowsAcquire;
                if (w.id == NOTIFICATION_EVENT_ID) {
                    sws[--nevts] = w;
                } else {

                    //
                    // Find the insertion position for *w*.
                    //

                    sws[k] = w;
                    int j = k - 1;
                    while (j >= 0 && sws[j].Id > w.Id) {
                        sws[j + 1] = sws[j];
                        j--;
                    }

                    //
                    // Insert at j+1 position.
                    //

                    sws[j + 1] = w;

                    //
                    // Check for duplicates.
                    //

                    if (sws[k - 1] == sws[k]) {
                        return -1;
                    }
                }
            }
            return acqAll ? 1 : 0;
        }
Exemplo n.º 15
0
        internal static bool WaitAllInternal(StWaitable[] ws, WaitHandle[] hs, StCancelArgs cargs) {
            if (ws == null) {
                throw new ArgumentNullException("ws");
            }

            int nevts;
            int len = ws.Length;
            StWaitable[] sws = new StWaitable[len];
            WaitHandle[] shs = null;

            int waitHint = SortAndCheckAllowAcquire(ws, sws, out nevts);
            
            if (waitHint < 0) {
                throw new ArgumentException("There are duplicate waitables", "ws");
            }

            if (hs != null) { 
                shs = Sort(hs);
                if (shs == null) {
                    throw new ArgumentException("There are duplicate wait handles", "hs");
                }
            }

            if (waitHint != 0 && shs != null && !WaitHandle.WaitAll(shs, 0)) {
                waitHint = 0;
            }

            //
            // Return success if all synchronizers are notification events and are set.
            //

            if (waitHint != 0 && nevts == 0) {
                return true;
            }

            if (waitHint == 0 && cargs.Timeout == 0) {
                return false;
            }

            //
            // If a timeout was specified, get the current time in order
            // to adjust the timeout value later, if we re-wait.
            //

            int lastTime = (cargs.Timeout != Timeout.Infinite) ? Environment.TickCount : 0;
            WaitBlock[] wbs = null;
            WaitBlock[] hints = null;
            do {
                if (waitHint == 0) {

                    //
                    // Create the wait block arrays if this is the first time
                    // that we execute the acquire-all prologue.
                    //
                    
                    if (wbs == null) {
                        wbs = new WaitBlock[len];
                        hints = new WaitBlock[len];
                    }

                    //
                    // Create a parker for cooperative release, specifying as many
                    // releasers as the number of waitables. The parker because is
                    // not reused because other threads may have references to it.
                    //

                    StParker pk = shs != null 
                                ? new StParker(len, EventBasedParkSpotFactory.Current.
                                                    Create(new WaitAllBehavior(shs)))
                                : new StParker(len);

                    int gsc = 1;
                    int sc = 0;
                    for (int i = 0; i < len; i++) {
                        if ((wbs[i] = sws[i]._WaitAllPrologue(pk, ref hints[i], ref sc)) == null) {
                            if (pk.TryLock()) {
                                pk.UnparkSelf(StParkStatus.StateChange);
                            }
                        } else if (gsc != 0) {
                            if (sc == 0) {
                                gsc = 0;
                            } else if (sc > gsc) {
                                gsc = sc;
                            }
                        }
                    }
                    
                    int wst = pk.Park(gsc, cargs);

                    //
                    // If the wait was cancelled due to timeout, alert or interrupt,
                    // cancel the acquire attempt on all waitables where we actually
                    // inserted wait blocks.
                    //

                    if (wst != StParkStatus.StateChange) {
                        for (int i = 0; i < len; i++) {
                            WaitBlock wb = wbs[i];
                            if (wb != null) {
                                sws[i]._CancelAcquire(wb, hints[i]);
                            }
                        }
                        
                        StCancelArgs.ThrowIfException(wst);
                        return false;
                    }
                }
            
                //
                // All waitables where we inserted wait blocks seem to allow 
                // an immediate acquire operation; so, try to acquire all of
                // them that are not notification events.
                //

                int idx;
                for (idx = 0; idx < nevts; idx++) {
                    if (!sws[idx]._TryAcquire()) {
                        break;
                    }
                }

                //
                // If all synchronizers were acquired, return success.
                //

                if (idx == nevts) {
                    return true;
                }

                //
                // We failed to acquire all waitables, so undo the acquires
                // that we did above.
                //

                while (--idx >= 0) {
                    sws[idx]._UndoAcquire();
                }

                if (shs != null) {
                    for (int i = 0; i < shs.Length; i++) {
                        shs[i].UndoAcquire();
                    }
                }

                //
                // If a timeout was specified, adjust the timeout value
                // that will be used on the next wait.
                //

                if (!cargs.AdjustTimeout(ref lastTime)) {
                    return false;
                }

                waitHint = 0;
            } while (true);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Waits until all of the specified waitables or wait handles can be 
        /// acquired, activating the specified cancellers.
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="hs"></param>
        /// <param name="cargs"></param>
        /// <returns></returns>
        public static bool WaitAll(StWaitable[] ws, WaitHandle[] hs, StCancelArgs cargs) {
            if (hs == null) {
                throw new ArgumentNullException("hs");
            }

            if (cargs.Alerter != null) {
                throw new ArgumentException("Cancellation through the alerter mechanism is not supported", "cargs");
            }

            return WaitAllInternal(ws, hs, cargs);
        }
Exemplo n.º 17
0
 /// <summary>
 /// Waits until all of the specified waitables can be acquired,
 /// activating the specified cancellers.
 /// </summary>
 /// <param name="ws"></param>
 /// <param name="cargs"></param>
 /// <returns></returns>
 public static bool WaitAll(StWaitable[] ws, StCancelArgs cargs) {
     return WaitAllInternal(ws, null, cargs);
 }
        //
        // Constructor: registers a wait with a Waitable synchronizer.
        //

        internal StRegisteredWait(StWaitable waitObject,  WaitOrTimerCallback callback,
                                  object cbState, int timeout, bool executeOnce) {

        	//
	        // Validate the arguments.
	        //

            if (timeout == 0) {
                throw new ArgumentOutOfRangeException("\"timeout\" can't be zero");
            }
            if (callback == null) {
                throw new ArgumentOutOfRangeException("\"callback\" can't be null");
            }
            if ((waitObject is StReentrantFairLock) || (waitObject is StReentrantReadWriteLock)) {
                throw new InvalidOperationException("can't register waits on reentrant locks");
            }
            if ((waitObject is StNotificationEvent) && !executeOnce) {
                throw new InvalidOperationException("Notification event can't register waits"
                            + " to execute more than once");
            }

	        //
	        // Initialize the register wait fields
	        //

            waitable = waitObject;
            cbparker = new CbParker(UnparkCallback);
            toTimer = new RawTimer(cbparker);
	        this.timeout = timeout;
            this.executeOnce = executeOnce;
	        this.callback = callback;
	        this.cbState = (cbState != null) ? cbState : this;
        
            //
	        // Execute the WaitAny prologue on the waitable.
	        //
            int ignored = 0;
            waitBlock  = waitObject._WaitAnyPrologue(cbparker, StParkStatus.Success, ref hint,
                                                     ref ignored);

            //
	        // Set the registered wait state to active and enable the
            // unpark callback.
	        //

	        state = ACTIVE;
            int ws = cbparker.EnableCallback(timeout, toTimer);
            if (ws != StParkStatus.Pending) {
		
                //
		        // The acquire operation was already accomplished. To prevent
                // uncontrolled reentrancy, the unpark callback is executed inline.
		        //

		        UnparkCallback(ws);
	        }
        }
Exemplo n.º 19
0
        //
        // Signals a waitable and waits on another as an atomic
        // operation, activating the specified cancellers.
        //

        public static bool SignalAndWait(StWaitable tos, StWaitable tow, StCancelArgs cargs) {
    
            //
            // Create a parker to execute the WaitAny prologue on the
            // *tow* waitable.
            //

            StParker pk = new StParker();
            WaitBlock hint = null;
            int sc = 0;
            WaitBlock wb = tow._WaitAnyPrologue(pk, StParkStatus.Success, ref hint, ref sc);

            //
            // Signal the *tos* waitable.
            //

            if (!tos._Release()) {

                //
                // The signal operation failed. So, try to cancel the parker and,
                // if successful, cancel the acquire attempt; otherwise, wait until 
                // the thread is unparked and, then, undo the acquire.
                //

                if (pk.TryCancel()) {
                    tow._CancelAcquire(wb, hint);
                } else {
                    pk.Park();
                    tow._UndoAcquire();
                }

                //
                // Report the failure appropriately.
                //

                throw tos._SignalException;
            }

            //
            // Park the current thread, activating the specified cancellers
            // and spinning if appropriate.
            //

            int ws = pk.Park(sc, cargs);

            //
            // If we acquired, execute the WaitOne epilogue and return success.
            //

            if (ws == StParkStatus.Success) {
                tow._WaitEpilogue();
                return true;
            }
    
            //
            // The acquire operation was cancelled; so, cancel the acquire
            // attempt and report the failure appropriately.
            //

            tow._CancelAcquire(wb, hint);
            StCancelArgs.ThrowIfException(ws);
            return false;
        }
Exemplo n.º 20
0
        //
        // Signals a waitable and waits unconditionally on another
        // as an atomic operation.
        //

        public static void SignalAndWait(StWaitable tos, StWaitable tow) {
            SignalAndWait(tos, tow, StCancelArgs.None);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Waits until one of the specified waitables can be acquired,
        /// activating the specified cancellers. 
        /// </summary>
        /// <param name="ws">The array of Waitables.</param>
        /// <param name="cargs">The cancellation arguments.</param>
        /// <returns></returns>
        public static int WaitAny(StWaitable[] ws, StCancelArgs cargs) {
            if (ws == null) {
                throw new ArgumentNullException("ws");
            }

            return WaitAnyInternal(ws, null, cargs);
        }