Beispiel #1
0
        internal void Start()
        {
            thread = Thread.CurrentThread;

            CurrentTaskScheduler = this;

            while (!stopRequested)
            {
                Task w = queuedTasks.Pop();

                if (w == null)
                {
                    TaskScheduler other = next;

                    while (other != this)
                    {
                        w = other.Steal();

                        if (w != null)
                        {
                            break;
                        }
                        other = other.next;
                    }

                    if (w == null)
                    {
                        if (!ThreadScheduler.StealDeque(this))
                        {
                            stopped = true;
                            CurrentTaskScheduler = null;
                            return;
                        }
                        else
                        {
                            continue;
                        }

                    }
                }

                // w should not be null at this point
                w.RunTask();

            } // end while(!stopRequested)

            // we have been stopped
            ThreadScheduler.AddTasks(queuedTasks);

            stopped = true;
            CurrentTaskScheduler = null;
        }
Beispiel #2
0
        internal static bool StealDeque(TaskScheduler tsStealer)
        {
            lock (dequeLock)
            {
                if (queuedTasks.Empty)
                    return false;
                else
                {
                    // swap deques
                    Deque<Task> tmp = tsStealer.QueuedTasks;
                    tsStealer.QueuedTasks = queuedTasks;
                    queuedTasks = tmp;
                    return true;
                }
            }

        }
Beispiel #3
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);

            }
        }
Beispiel #4
0
        private static void CreateTaskScheduler()
        {
            TaskScheduler ts = new TaskScheduler();

            if (last == null) // we have no TaskSchedulers
            {
                last = ts;
                // we make it point to itself
                ts.Next = ts;
            }
            else
            {
                ts.Next = last.Next;
                last.Next = ts;
                last = ts;
            }

            if (!queuedTasks.Empty)
                StealDeque(ts);

            JibuThreadPool.runTask(ts.Start);
        }