/// <summary> /// Notify that a new task has been created for the given machine. /// </summary> /// <param name="id">TaskId</param> /// <param name="machine">Machine</param> internal override void NotifyNewTaskCreated(int id, BaseMachine machine) { var taskInfo = new TaskInfo(id, machine); Output.Debug("<ScheduleDebug> Created task {0} for machine {1}({2}).", taskInfo.Id, taskInfo.Machine.GetType(), taskInfo.Machine.Id.MVal); if (this.Tasks.Count == 0) { taskInfo.IsActive = true; } this.Tasks.Add(taskInfo); this.TaskMap.Add(id, taskInfo); if (machine is TaskMachine) { this.WrappedTaskMap.Add((machine as TaskMachine).WrappedTask.Id, taskInfo); } }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="machines">Machines</param> /// <returns>Boolean value</returns> bool ISchedulingStrategy.TryGetNext(out TaskInfo next, List<TaskInfo> tasks) { var enabledTasks = tasks.Where(task => task.IsEnabled).ToList(); if (enabledTasks.Count == 0) { next = null; return false; } int id = this.Random.Next(enabledTasks.Count); next = enabledTasks[id]; return true; }
/// <summary> /// Notify that a new task has been created for the given machine. /// </summary> /// <param name="id">TaskId</param> /// <param name="machine">Machine</param> internal void NotifyNewTaskCreated(int id, Machine machine) { var taskInfo = new TaskInfo(id, machine); Output.Debug(DebugType.Testing, "<ScheduleDebug> Created task {0} for machine {1}({2}).", taskInfo.Id, taskInfo.Machine.GetType(), taskInfo.Machine.Id.MVal); if (this.Tasks.Count == 0) { taskInfo.IsActive = true; } this.TaskMap.Add(id, taskInfo); this.Tasks.Add(taskInfo); }
/// <summary> /// Returns the next task to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="tasks">Tasks</param> /// <param name="currentTask">Curent task</param> /// <returns>Boolean value</returns> public bool TryGetNext(out TaskInfo next, List<TaskInfo> tasks, TaskInfo currentTask) { var enabledTasks = tasks.Where(task => task.IsEnabled).ToList(); if (enabledTasks.Count == 0) { next = null; return false; } var availableTasks = enabledTasks.Where( task => !task.IsBlocked && !task.IsWaiting).ToList(); if (availableTasks.Count == 0) { next = null; return false; } int id = this.Random.Next(availableTasks.Count); next = availableTasks[id]; if (!currentTask.IsCompleted) { this.SchedulingSteps++; } return true; }
/// <summary> /// Schedules the next machine to execute. /// </summary> internal override void Schedule() { int?id = Task.CurrentId; if (id == null || id == PSharpRuntime.RootTaskId) { return; } if (this.Strategy.HasReachedDepthBound()) { Output.Debug("<ScheduleDebug> Depth bound of {0} reached.", this.Strategy.GetDepthBound()); this.KillRemainingTasks(); throw new TaskCanceledException(); } foreach (var task in this.Tasks.Where(val => val.IsBlocked)) { foreach (var userTask in this.UserTasks.Where(val => val.IsCompleted)) { if (task.BlockingUnwrappedTasks.Contains(userTask)) { task.BlockingUnwrappedTasks.Remove(userTask); if (!task.WaitAll) { task.BlockingWrappedTasks.Clear(); task.BlockingUnwrappedTasks.Clear(); task.IsBlocked = false; break; } } } if (task.WaitAll && task.BlockingWrappedTasks.Count == 0 && task.BlockingUnwrappedTasks.Count == 0) { task.WaitAll = false; task.IsBlocked = false; } if (!task.IsBlocked) { Output.Debug("<ScheduleDebug> Unblocked task {0} of " + "machine {1}({2}).", task.Id, task.Machine.GetType(), task.Machine.Id.MVal); } } TaskInfo taskInfo = null; if (this.TaskMap.ContainsKey((int)id)) { taskInfo = this.TaskMap[(int)id]; } else if (this.WrappedTaskMap.ContainsKey((int)id)) { taskInfo = this.WrappedTaskMap[(int)id]; } else { Output.Debug("<ScheduleDebug> Unable to schedule task {0}.", id); this.KillRemainingTasks(); throw new TaskCanceledException(); } TaskInfo next = null; if (!this.Strategy.TryGetNext(out next, this.Tasks, taskInfo)) { Output.Debug("<ScheduleDebug> Schedule explored."); this.KillRemainingTasks(); throw new TaskCanceledException(); } PSharpRuntime.ProgramTrace.AddSchedulingChoice(next.Machine); if (PSharpRuntime.Configuration.CheckLiveness && PSharpRuntime.Configuration.CacheProgramState && PSharpRuntime.Configuration.SafetyPrefixBound <= this.SchedulingPoints) { PSharpRuntime.StateCache.CaptureState(PSharpRuntime.ProgramTrace.Peek()); } Output.Debug("<ScheduleDebug> Schedule task {0} of machine {1}({2}).", next.Id, next.Machine.GetType(), next.Machine.Id.MVal); if (taskInfo != next) { taskInfo.IsActive = false; lock (next) { next.IsActive = true; System.Threading.Monitor.PulseAll(next); } lock (taskInfo) { if (taskInfo.IsCompleted) { return; } while (!taskInfo.IsActive) { Output.Debug("<ScheduleDebug> Sleep task {0} of machine {1}({2}).", taskInfo.Id, taskInfo.Machine.GetType(), taskInfo.Machine.Id.MVal); System.Threading.Monitor.Wait(taskInfo); Output.Debug("<ScheduleDebug> Wake up task {0} of machine {1}({2}).", taskInfo.Id, taskInfo.Machine.GetType(), taskInfo.Machine.Id.MVal); } if (!taskInfo.IsEnabled) { throw new TaskCanceledException(); } } } }
/// <summary> /// Returns the next task to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="tasks">Tasks</param> /// <param name="currentTask">Curent task</param> /// <returns>Boolean value</returns> public bool TryGetNext(out TaskInfo next, List<TaskInfo> tasks, TaskInfo currentTask) { var enabledTasks = tasks.Where(task => task.IsEnabled).ToList(); if (enabledTasks.Count == 0) { next = null; return false; } var availableTasks = enabledTasks.Where( task => !task.IsBlocked && !task.IsWaiting).ToList(); if (availableTasks.Count == 0) { next = null; return false; } SChoice nextChoice = null; List<SChoice> scs = null; if (this.SchIndex < this.ScheduleStack.Count) { scs = this.ScheduleStack[this.SchIndex]; } else { scs = new List<SChoice>(); foreach (var task in availableTasks) { scs.Add(new SChoice(task.Machine.Id.Value)); } this.ScheduleStack.Add(scs); } nextChoice = scs.FirstOrDefault(val => !val.IsDone); if (nextChoice == null) { next = null; return false; } if (this.SchIndex > 0) { var previousChoice = this.ScheduleStack[this.SchIndex - 1].Last(val => val.IsDone); previousChoice.IsDone = false; } next = availableTasks.Find(task => task.Machine.Id.Value == nextChoice.Id); nextChoice.IsDone = true; this.SchIndex++; if (next == null) { return false; } if (!currentTask.IsCompleted) { this.SchedulingSteps++; } return true; }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="machines">Machines</param> /// <returns>Boolean value</returns> bool ISchedulingStrategy.TryGetNext(out TaskInfo next, List<TaskInfo> tasks) { var enabledTasks = tasks.Where(task => task.IsEnabled).ToList(); if (enabledTasks.Count == 0) { next = null; return false; } SChoice nextChoice = null; List<SChoice> scs = null; if (this.SchIndex < this.ScheduleStack.Count) { scs = this.ScheduleStack[this.SchIndex]; } else { scs = new List<SChoice>(); foreach (var task in enabledTasks) { scs.Add(new SChoice(task.Machine.Id.Value)); } this.ScheduleStack.Add(scs); } nextChoice = scs.FirstOrDefault(val => !val.IsDone); if (nextChoice == null) { next = null; return false; } if (this.SchIndex > 0) { var previousChoice = this.ScheduleStack[this.SchIndex - 1].Last(val => val.IsDone); previousChoice.IsDone = false; } next = enabledTasks.Find(task => task.Machine.Id.Value == nextChoice.Id); nextChoice.IsDone = true; this.SchIndex++; if (next == null) { return false; } return true; }