Beispiel #1
0
 public Future Reschedule(AbstractTask task, Condition condition)
 {
     lock (syncLock)
     {
         totalTasks += 1;
         if (task.ExecutionState == ExecutionState.Running)
         {
             Interlocked.Decrement(ref currentRunningProcessCount);
         }
         task.ExecutionState = ExecutionState.Scheduled;
         CurrentThreadQueuedTasks.AddLast(new SchedulePair(task, condition));
         Monitor.PulseAll(syncLock);
     }
     return(task.Completed);
 }
Beispiel #2
0
        /// <summary>
        /// This must run under the lock!
        /// </summary>
        private bool?TryGetTaskToRun(ref AbstractTask task)
        {
            //this approach gives us an O(1) _removal_ cost from the list
            LinkedListNode <SchedulePair> node = CurrentThreadQueuedTasks.First;

            while (node != null)
            {
                SchedulePair pair = node.Value;
                if (pair.Condition())
                {
                    task = pair.Task;
                    CurrentThreadQueuedTasks.Remove(node);
                    break;
                }
                pair.CannotRunCount += 1;
                //this is probably a process that is waiting for other processes
                //move it to the end of the list so we don't have to iterate over it all
                //the time
                LinkedListNode <SchedulePair> prev = node;
                node = node.Next;
                if (pair.CannotRunCount == 3 && Status != ScheduleStatus.Idle)
                {
                    pair.CannotRunCount = -1; //give it a bit of a boost for the next time
                    CurrentThreadQueuedTasks.Remove(prev);
                    CurrentThreadQueuedTasks.AddLast(prev);
                }
            }
            if (task == null) // no tasks to run in the curren threa, time to steal some work...
            {
                StealWorkFromAnotherThread();
                //nothing runs, and there are no tasks that we _can_ run
                // we are either deadlocked or waiting for an external resource
                // we will let the idle task decide what to do.
                if (currentRunningProcessCount == 0)
                {
                    Status = ScheduleStatus.Idle;
                    task   = idleTask;
                    return(true);
                }
            }
            return(null);
        }