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();
        }
        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();
        }