Пример #1
0
        public bool IsSafe(DcrGraph safeForDcrGraph)
        {
            //acyclic
            var dependencyGraph = this.BuildDependencyGraph();
            var cycleChecker    = new CycleChecker();
            var cycle           = cycleChecker.ExistsCycleConditionMilestone(dependencyGraph);
            var cycleResponse   = cycleChecker.ExistsCycleResponse(dependencyGraph);

            if (cycle != null || cycleResponse != null)
            {
                return(false);
            }

            // no include, exclude or response to any activity
            if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y =>
                                                                  y.Type == Relation.RelationType.Include || y.Type == Relation.RelationType.Exclude ||
                                                                  y.Type == Relation.RelationType.Response)))
            {
                return(false);
            }

            // np-hard? Check any outgoing condition/milestone reachable
            if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y =>
                                                                  (y.Type == Relation.RelationType.Condition || y.Type == Relation.RelationType.Milestone) &&
                                                                  !ReachableFromTo(y.From, y.To, safeForDcrGraph))))
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        private void FindDeadlocks()
        {
            var cycleChecker = new CycleChecker();

            foreach (var dcrGraph in DcrGraphs)
            {
                var cycles = cycleChecker.GetAllCycleConditionMilestone(dcrGraph.Activities);
                if (cycles != null)
                {
                    var breakAble = false;
                    // check any event included and no incoming except include
                    breakAble = dcrGraph.Activities.Any(x =>
                                                        !x.Excluded && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Include));
                    if (breakAble)
                    {
                        return;
                    }

                    // check exists safe event which can not be excluded
                    foreach (var activity in dcrGraph.Activities)
                    {
                        if (activity.IsSafe(dcrGraph) &&
                            activity._relationsIncoming.All(x => x.Type != Relation.RelationType.Exclude))
                        {
                            breakAble = true;
                        }
                    }

                    if (breakAble)
                    {
                        return;
                    }

                    var cyclesBreakAble = new List <bool>();

                    foreach (var cycle in cycles)
                    {
                        breakAble = cycle.Any(x =>
                                              x._relationsIncoming.All(y => y.Type != Relation.RelationType.Include) &&
                                              x._relationsIncoming.All(y =>
                                                                       y.Type == Relation.RelationType.Exclude && y.From.IsSafe(dcrGraph)));
                        cyclesBreakAble.Add(breakAble);
                    }

                    for (var index = 0; index < cyclesBreakAble.Count; index++)
                    {
                        var breakable = cyclesBreakAble[index];
                        if (breakable)
                        {
                            continue;
                        }
                        var cycle = cycles[index];
                        if (cycle.All(x =>
                                      !x.Pending && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Response) && dcrGraph.Activities.All(y => !y.Pending)))
                        {
                            cyclesBreakAble[index] = true;
                        }
                    }

                    for (var index = 0; index < cyclesBreakAble.Count; index++)
                    {
                        var b     = cyclesBreakAble[index];
                        var cycle = cycles[index];
                        if (!b)
                        {
                            Deadlocks.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle));
                        }
                    }
                }
            }
        }
Пример #3
0
        private void FindLivelocks()
        {
            var cycleChecker = new CycleChecker();

            foreach (var dcrGraph in DcrGraphs)
            {
                var deadCycles = cycleChecker.GetAllCycleConditionMilestone(dcrGraph.Activities);
                var liveCycles = cycleChecker.GetAllCycleResponse(dcrGraph.Activities);
                if (liveCycles == null && deadCycles == null)
                {
                    return;
                }

                var noDead = new List <bool>();

                if (deadCycles != null)
                {
                    foreach (var deadCycle in deadCycles)
                    {
                        if (deadCycle.All(x =>
                                          !x.Pending && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Response)))
                        {
                            if (deadCycle.Any(x => x._relationsOutgoing.Any(y =>
                                                                            (y.Type == Relation.RelationType.Condition ||
                                                                             y.Type == Relation.RelationType.Milestone) && !y.To.Id.Equals(y.From.Id))))
                            {
                                noDead.Add(false);
                                continue;
                            }
                            noDead.Add(true);
                            continue;
                        }

                        var possiblyPending = deadCycle.Where(x =>
                                                              x.Pending || x._relationsIncoming.Any(y => y.Type == Relation.RelationType.Response)).ToList();
                        if (possiblyPending.Any())
                        {
                            foreach (var activity in possiblyPending)
                            {
                                var graphWithNoExcludeToActivityBeingTested = new DcrGraph(dcrGraph.EditWindowString, new List <string>(), dcrGraph.EditWindowString, "graphWithNoRelationsToActivityBeingTested");
                                var perhapsSafeActivity =
                                    graphWithNoExcludeToActivityBeingTested.Activities.Where(x =>
                                                                                             x._relationsOutgoing.Any(y => y.To.Id.Equals(activity.Id) && y.Type == Relation.RelationType.Exclude)).ToList();

                                foreach (var activity1 in perhapsSafeActivity)
                                {
                                    activity1._relationsOutgoing.Remove(activity1._relationsOutgoing.First(x =>
                                                                                                           x.Type == Relation.RelationType.Exclude && x.To.Id.Equals(activity.Id)));
                                }

                                var anySafeExlude = perhapsSafeActivity.Any(x =>
                                                                            x.IsSafe(graphWithNoExcludeToActivityBeingTested) && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Exclude));

                                if (!(activity.Excluded || anySafeExlude))
                                {
                                    noDead.Add(false);
                                    break;
                                }
                                else
                                {
                                    noDead.Add(true);
                                }
                            }
                            //noDead.Add(true);
                        }
                        else
                        {
                            noDead.Add(true);
                        }
                    }

                    for (int i = 0; i < deadCycles.Count; i++)
                    {
                        var  cycle = deadCycles[i];
                        bool live  = noDead[i];
                        if (!live)
                        {
                            Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle));
                        }
                    }
                }

                var noLive = new List <bool>();

                if (liveCycles != null)
                {
                    foreach (var liveCycle in liveCycles)
                    {
                        // all safe
                        if (liveCycle.All(x => x.IsSafe(dcrGraph)))
                        {
                            noLive.Add(true);
                            continue;
                        }


                        // exist always excluded never included in circle
                        if (liveCycle.Any(x =>
                                          (x.Excluded && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Include)) ||
                                          x._relationsIncoming.Any(y =>
                                                                   y.Type == Relation.RelationType.Exclude && y.From.IsSafe(CreateXE(dcrGraph, y.From)) &&
                                                                   y.From._relationsIncoming.All(z => z.Type != Relation.RelationType.Exclude)) &&
                                          x._relationsIncoming.All(c => c.Type != Relation.RelationType.Include)))
                        {
                            noLive.Add(true);
                            continue;
                        }

                        noLive.Add(false);
                    }

                    for (int i = 0; i < liveCycles.Count; i++)
                    {
                        var  cycle = liveCycles[i];
                        bool live  = noLive[i];
                        if (!live)
                        {
                            Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle));
                        }
                    }
                }
            }
        }