Ejemplo n.º 1
0
        internal static void Start()
        {
            while (true)
            {
                int  numThreads        = 0;
                int  numBlockedThreads = 0;
                int  numStopRequested  = 0;
                bool anyQueuedTasks    = false;

                if (last != null)
                {
                    // this is a little messy, but must work for 1 or more threads.
                    TaskScheduler cur  = last.Next;
                    TaskScheduler prev = last;

                    bool done = false;

                    while (!done)
                    {
                        if (cur == last) // is this the last iteration?
                        {
                            done = true;
                        }

                        if (cur.IsStopped)
                        {
                            if (cur == prev) // there's only one thread
                            {
                                last = null;
                                break;
                            }
                            else
                            {
                                // remove cur, prev does not change
                                prev.Next = cur.Next;

                                if (cur == last) // we're removing the last thread
                                {
                                    last = prev;
                                }
                            }
                        }
                        else
                        {
                            numThreads++;

                            if (cur.Thread != null && (cur.Thread.ThreadState & ThreadState.WaitSleepJoin) == ThreadState.WaitSleepJoin)
                            {
                                numBlockedThreads++;
                            }

                            if (!cur.QueuedTasks.Empty)
                            {
                                anyQueuedTasks = true;
                            }

                            if (cur.StopRequested)
                            {
                                numStopRequested++;
                            }

                            if (numThreads - numBlockedThreads - numStopRequested > numCores)
                            {
                                numStopRequested++;
                                cur.StopRequested = true;
                            }

                            prev = cur;
                        }
                        cur = cur.Next;
                    }
                }

                int numRunningThreads = numThreads - numBlockedThreads;

                if (numCores > numRunningThreads)
                {
                    if (!queuedTasks.Empty || anyQueuedTasks)
                    {
                        int numNewScheds = numCores - numRunningThreads;

                        for (int i = 0; i < numNewScheds; i++)
                        {
                            CreateTaskScheduler();
                        }
                    }
                    else if (numThreads == 0)
                    {
                        Monitor.Enter(dequeLock);

                        if (queuedTasks.Empty)
                        {
                            waiting = true;
                            Monitor.Wait(dequeLock);
                            Monitor.Exit(dequeLock);
                        }
                        else
                        {
                            Monitor.Exit(dequeLock);
                            for (int i = 0; i < numCores; i++)
                            {
                                CreateTaskScheduler();
                            }
                        }
                    }
                }

                Timer.SleepFor(sleepTime);
            }
        }