/// <summary> /// Constructor. /// </summary> /// <param name="fingerprint">Fingerprint</param> /// <param name="enabledMachines">Enabled machines</param> /// <param name="monitorStatus">Monitor status</param> internal State(Fingerprint fingerprint, HashSet<AbstractMachine> enabledMachines, Dictionary<Monitor, MonitorStatus> monitorStatus) { this.Fingerprint = fingerprint; this.EnabledMachines = enabledMachines; this.MonitorStatus = monitorStatus; }
/// <summary> /// Initializes a new instance of the <see cref="State"/> class. /// </summary> internal State(Fingerprint fingerprint, HashSet <ulong> enabledMachineIds, Dictionary <Monitor, MonitorStatus> monitorStatus) { this.Fingerprint = fingerprint; this.EnabledMachineIds = enabledMachineIds; this.MonitorStatus = monitorStatus; }
/// <summary> /// Checks liveness at a schedule trace cycle. /// </summary> /// <param name="root">Cycle start</param> internal void CheckLivenessAtTraceCycle(Fingerprint root) { // If there is a potential cycle found, do not create a new // one until the liveness checker has finished exploring the // current cycle. if (this.PotentialCycle.Count > 0) { return; } do { var scheduleStep = this.Runtime.ScheduleTrace.Pop(); var state = this.Runtime.StateCache[scheduleStep]; this.PotentialCycle.Insert(0, Tuple.Create(scheduleStep, state)); IO.Debug("<LivenessDebug> Cycle contains {0} with {1}.", scheduleStep.Type, state.Fingerprint.ToString()); // The state can be safely removed, because the liveness detection // algorithm currently removes cycles, so a specific state can only // appear once in the schedule trace. this.Runtime.StateCache.Remove(scheduleStep); } while (this.Runtime.ScheduleTrace.Peek() != null && !this.Runtime.StateCache[ this.Runtime.ScheduleTrace.Peek()].Fingerprint.Equals(root)); IO.Debug("<LivenessDebug> ------------ SCHEDULE ------------."); foreach (var x in this.Runtime.ScheduleTrace) { if (x.Type == ScheduleStepType.SchedulingChoice) { IO.Debug($"{x.Index} :: {x.Type} :: {x.ScheduledMachine.Id} :: {this.Runtime.StateCache[x].Fingerprint}"); } else if (x.BooleanChoice != null) { IO.Debug($"{x.Index} :: {x.Type} :: {x.BooleanChoice.Value} :: {this.Runtime.StateCache[x].Fingerprint}"); } else { IO.Debug($"{x.Index} :: {x.Type} :: {x.IntegerChoice.Value} :: {this.Runtime.StateCache[x].Fingerprint}"); } } IO.Debug("<LivenessDebug> ----------------------------------."); IO.Debug("<LivenessDebug> ------------- CYCLE --------------."); foreach (var x in this.PotentialCycle) { if (x.Item1.Type == ScheduleStepType.SchedulingChoice) { IO.Debug($"{x.Item1.Index} :: {x.Item1.Type} :: {x.Item1.ScheduledMachine.Id}"); } else if (x.Item1.BooleanChoice != null) { IO.Debug($"{x.Item1.Index} :: {x.Item1.Type} :: {x.Item1.BooleanChoice.Value}"); } else { IO.Debug($"{x.Item1.Index} :: {x.Item1.Type} :: {x.Item1.IntegerChoice.Value}"); } x.Item2.PrettyPrint(); } IO.Debug("<LivenessDebug> ----------------------------------."); if (!this.IsSchedulingFair(this.PotentialCycle)) { IO.Debug("<LivenessDebug> Scheduling in cycle is unfair."); this.PotentialCycle.Clear(); return; } else if (!this.IsNondeterminismFair(this.PotentialCycle)) { IO.Debug("<LivenessDebug> Nondeterminism in cycle is unfair."); this.PotentialCycle.Clear(); return; } IO.Debug("<LivenessDebug> Cycle execution is fair."); this.HotMonitors = this.GetHotMonitors(this.PotentialCycle); if (this.HotMonitors.Count > 0) { this.EndOfCycleIndex = this.PotentialCycle.Select(val => val.Item1).Max(val => val.Index); this.Runtime.BugFinder.SwitchSchedulingStrategy(this); } else { this.PotentialCycle.Clear(); } }