Esempio n. 1
0
 /// <summary>
 /// Sets the next operation to schedule.
 /// </summary>
 /// <param name="operationType">Type of the operation.</param>
 /// <param name="targetType">Type of the target of the operation.</param>
 /// <param name="targetId">Id of the target.</param>
 internal void SetNextOperation(OperationType operationType, OperationTargetType targetType, ulong targetId)
 {
     NextOperationType = operationType;
     NextTargetType    = targetType;
     NextTargetId      = targetId;
     OperationCount++;
     EventHandlerOperationCount++;
 }
Esempio n. 2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="id"></param>
 /// <param name="enabled"></param>
 /// <param name="opType"></param>
 /// <param name="targetType"></param>
 /// <param name="targetId"></param>
 /// <param name="sendStepIndex"></param>
 public TidEntry(int id, bool enabled, OperationType opType, OperationTargetType targetType, int targetId, int sendStepIndex)
 {
     Id            = id;
     Enabled       = enabled;
     Sleep         = false;
     Backtrack     = false;
     OpType        = opType;
     TargetType    = targetType;
     TargetId      = targetId;
     SendStepIndex = sendStepIndex;
 }
Esempio n. 3
0
        /// <summary>
        /// Schedules the next <see cref="ISchedulable"/> operation to execute.
        /// </summary>
        /// <param name="operationType">Type of the operation.</param>
        /// <param name="targetType">Type of the target of the operation.</param>
        /// <param name="targetId">Id of the target.</param>
        internal void Schedule(OperationType operationType, OperationTargetType targetType, ulong targetId)
        {
            int?taskId = Task.CurrentId;

            // If the caller is the root task, then return.
            if (taskId != null && taskId == this.Runtime.RootTaskId)
            {
                return;
            }

            if (!this.IsSchedulerRunning)
            {
                this.Stop();
            }

            // Checks if synchronisation not controlled by P# was used.
            this.CheckIfExternalSynchronizationIsUsed();

            // Checks if the scheduling steps bound has been reached.
            this.CheckIfSchedulingStepsBoundIsReached();

            SchedulableInfo current = this.ScheduledMachine;

            current.SetNextOperation(operationType, targetType, targetId);

            // Get and order the schedulable choices by their id.
            var choices = this.SchedulableInfoMap.Values.OrderBy(choice => choice.Id).Select(choice => choice as ISchedulable).ToList();

            ISchedulable next = null;

            if (!this.Strategy.GetNext(out next, choices, current))
            {
                // Checks if the program has livelocked.
                this.CheckIfProgramHasLivelocked(choices.Select(choice => choice as SchedulableInfo));

                Debug.WriteLine("<ScheduleDebug> Schedule explored.");
                this.HasFullyExploredSchedule = true;
                this.Stop();
            }

            this.ScheduledMachine = next as SchedulableInfo;

            this.Runtime.ScheduleTrace.AddSchedulingChoice(next.Id);
            (next as MachineInfo).ProgramCounter = 0;

            Debug.WriteLine($"<ScheduleDebug> Schedule '{next.Name}' with task id '{this.ScheduledMachine.TaskId}'.");

            if (current != next)
            {
                current.IsActive = false;
                lock (next)
                {
                    this.ScheduledMachine.IsActive = true;
                    System.Threading.Monitor.PulseAll(next);
                }

                lock (current)
                {
                    if (!current.IsEventHandlerRunning)
                    {
                        return;
                    }

                    while (!current.IsActive)
                    {
                        Debug.WriteLine($"<ScheduleDebug> Sleep '{current.Name}' with task id '{current.TaskId}'.");
                        System.Threading.Monitor.Wait(current);
                        Debug.WriteLine($"<ScheduleDebug> Wake up '{current.Name}' with task id '{current.TaskId}'.");
                    }

                    if (!current.IsEnabled)
                    {
                        throw new ExecutionCanceledException();
                    }
                }
            }
        }