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; }
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); }
/// <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); }
protected Future Spawn(AbstractTask task) { return(scheduler.Schedule(task)); }
protected Future Spawn(AbstractTask task) { return scheduler.Schedule(task); }
public Future Schedule(AbstractTask task) { task.Initialize(this); return Reschedule(task, delegate { return true; }); }
public SchedulePair(AbstractTask task, Condition condition) { Task = task; Condition = condition; }
public void Completed(AbstractTask task) { lock (syncLock) { Interlocked.Decrement(ref currentRunningProcessCount); Monitor.PulseAll(syncLock); } }
/// <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; }
public void ScheduleFirst(AbstractTask task) { lock (syncLock) { task.ExecutionState = ExecutionState.Scheduled; CurrentThreadQueuedTasks.AddFirst(new SchedulePair(task, delegate { return true; })); Monitor.PulseAll(syncLock); } }
public Future Schedule(AbstractTask task) { task.Initialize(this); return(Reschedule(task, delegate { return true; })); }