From cdffd7ee93f8f91501043051cf1992cd4a25a153 Mon Sep 17 00:00:00 2001 From: Michael Schmid Date: Thu, 7 May 2020 11:43:11 +0200 Subject: [PATCH] Creation of NFJ DAG --- src/main/java/mvd/jester/App.java | 2 +- src/main/java/mvd/jester/model/DagTask.java | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- src/main/java/mvd/jester/tests/FonsecaNelis.java | 21 +++++++++++++++++++-- 3 files changed, 129 insertions(+), 10 deletions(-) diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index c24ddcf..8d05e8c 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -16,7 +16,7 @@ import mvd.jester.tests.SchmidMottok; */ public class App { public static void main(String[] args) { - for (int p = 4; p <= 4; p *= 2) { + for (int p = 8; p <= 8; p *= 2) { SystemSetup.DagTaskBuilder builder = new SystemSetup.DagTaskBuilder().setNumberOfProcessors(p); TestEnvironment te = new TestEnvironment(); diff --git a/src/main/java/mvd/jester/model/DagTask.java b/src/main/java/mvd/jester/model/DagTask.java index 1297c99..a0d818d 100644 --- a/src/main/java/mvd/jester/model/DagTask.java +++ b/src/main/java/mvd/jester/model/DagTask.java @@ -1,9 +1,14 @@ package mvd.jester.model; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Set; +import org.jgrapht.Graphs; import org.jgrapht.experimental.dag.DirectedAcyclicGraph; import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.traverse.BreadthFirstIterator; public class DagTask implements Task { @@ -154,11 +159,70 @@ public class DagTask implements Task { return segments; } - public static void createNFJGraph(DirectedAcyclicGraph jobDag) { - Set joinNodes = new LinkedHashSet<>(); - Set forkNodes = new LinkedHashSet<>(); + public static DirectedAcyclicGraph createNFJGraph( + DirectedAcyclicGraph jobDag) { + DirectedAcyclicGraph modifiedJobDag = + new DirectedAcyclicGraph<>(DefaultEdge.class); + Graphs.addGraph(modifiedJobDag, jobDag); + LinkedList joinNodes = new LinkedList<>(); + List forkNodes = new LinkedList<>(); - for (Job j : jobDag) { + BreadthFirstIterator breadthFirstIterator = + new BreadthFirstIterator<>(modifiedJobDag); + while (breadthFirstIterator.hasNext()) { + Job j = breadthFirstIterator.next(); + if (modifiedJobDag.inDegreeOf(j) > 1) { + joinNodes.add(j); + } + if (modifiedJobDag.outDegreeOf(j) > 1) { + forkNodes.add(j); + } + } + + Job sink = joinNodes.getLast(); + + for (Job j : joinNodes) { + Set edgeSet = new HashSet<>(modifiedJobDag.incomingEdgesOf(j)); + for (DefaultEdge e : edgeSet) { + Job predecessor = modifiedJobDag.getEdgeSource(e); + boolean satisfiesProposition = + DagUtils.checkForFork(modifiedJobDag, j, forkNodes, predecessor); + if (!satisfiesProposition) { + modifiedJobDag.removeEdge(e); + if (modifiedJobDag.outgoingEdgesOf(predecessor).isEmpty()) { + try { + modifiedJobDag.addDagEdge(predecessor, sink); + } catch (Exception ex) { + } + } + } + + if (modifiedJobDag.inDegreeOf(j) == 1) { + break; + } + } + // Find fork node f following the path along this edge e + // if f has successor that is not ancestor of j -> e is conflicting edge + // get sorcetarget of e + // remove e + // if sourcetarget has no successor -> connect sourcetraget to sink + // if indegree = 1 -> break; + } + + // if (!DagUtils.checkProperty1(modifiedJobDag)) { + // throw new RuntimeException("abs"); + // } + return modifiedJobDag; + } + + private static boolean checkProperty1(DirectedAcyclicGraph jobDag) { + LinkedList joinNodes = new LinkedList<>(); + List forkNodes = new LinkedList<>(); + + BreadthFirstIterator breadthFirstIterator = + new BreadthFirstIterator<>(jobDag); + while (breadthFirstIterator.hasNext()) { + Job j = breadthFirstIterator.next(); if (jobDag.inDegreeOf(j) > 1) { joinNodes.add(j); } @@ -168,11 +232,49 @@ public class DagTask implements Task { } for (Job j : joinNodes) { - for (Job f : forkNodes) { - Set edges = jobDag.getAllEdges(f, j); - // jobDag. + nextFork: for (Job f : forkNodes) { + Set edgeSet = jobDag.getAllEdges(f, j); + + for (DefaultEdge e : edgeSet) { + Job a = jobDag.getEdgeSource(e); + if (a != f) { + Set succAndPred = new HashSet<>(); + succAndPred.addAll(Graphs.predecessorListOf(jobDag, a)); + succAndPred.addAll(Graphs.successorListOf(jobDag, a)); + + for (Job b : succAndPred) { + if (!((jobDag.getAncestors(jobDag, j).contains(b) || b == j) + && (jobDag.getDescendants(jobDag, f).contains(b) + || b == f))) { + continue nextFork; + } + } + } + } + return true; + } + } + return false; + } + + private static boolean checkForFork(DirectedAcyclicGraph jobDag, + Job joinNode, List forkNodes, Job job) { + List pred = Graphs.predecessorListOf(jobDag, job); + + for (Job p : pred) { + if (forkNodes.contains(p)) { + for (DefaultEdge successorEdge : jobDag.outgoingEdgesOf(p)) { + Job successor = jobDag.getEdgeSource(successorEdge); + if (jobDag.getAncestors(jobDag, joinNode).contains(successor)) { + return false; + } + } + } else { + return checkForFork(jobDag, joinNode, forkNodes, p); } } + + return true; } } diff --git a/src/main/java/mvd/jester/tests/FonsecaNelis.java b/src/main/java/mvd/jester/tests/FonsecaNelis.java index ebb2bf5..425ddb6 100644 --- a/src/main/java/mvd/jester/tests/FonsecaNelis.java +++ b/src/main/java/mvd/jester/tests/FonsecaNelis.java @@ -9,13 +9,17 @@ import java.util.Map; import java.util.Set; import com.google.common.collect.Lists; import com.google.common.math.LongMath; +import org.jgrapht.experimental.dag.DirectedAcyclicGraph; +import org.jgrapht.graph.DefaultEdge; import mvd.jester.info.SchedulingInfo; import mvd.jester.info.TerminationInfo; import mvd.jester.info.TerminationInfo.Level; import mvd.jester.model.DagTask; +import mvd.jester.model.Job; import mvd.jester.model.Segment; import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; +import mvd.jester.model.DagTask.DagUtils; import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; @@ -23,11 +27,13 @@ public class FonsecaNelis extends AbstractTest { private final Map responseTimes; private final PriorityManager priorityManager; + private final Map> sortedSegments; public FonsecaNelis(long numberOfProcessors) { super(numberOfProcessors); this.responseTimes = new HashMap<>(); this.priorityManager = new RateMonotonic(); + this.sortedSegments = new HashMap<>(); } @Override @@ -37,8 +43,9 @@ public class FonsecaNelis extends AbstractTest { @Override public SchedulingInfo runSchedulabilityCheck(SortedTaskSet tasks) { - createNFJandDecompositionTree(tasks); + sortedSegments.clear(); responseTimes.clear(); + createNFJandDecompositionTree(tasks); for (DagTask t : tasks) { long responseTime = calculateResponseTime(tasks, t); responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime, Level.HIGH)); @@ -49,6 +56,16 @@ public class FonsecaNelis extends AbstractTest { } private void createNFJandDecompositionTree(SortedTaskSet tasks) { + for (DagTask t : tasks) { + DirectedAcyclicGraph modifiedJobDag = + DagUtils.createNFJGraph(t.getJobDag()); + // List sortedSegment = new LinkedList<>(t.getWorkloadDistribution()); + // Collections.sort(sortedSegment, + // (s1, s2) -> (int) (s2.getNumberOfJobs() - s1.getNumberOfJobs())); + + // Set sortedSet = new LinkedHashSet<>(sortedSegment); + // sortedSegments.put(t, sortedSet); + } } private long calculateResponseTime(SortedTaskSet tasks, DagTask task) { @@ -90,7 +107,7 @@ public class FonsecaNelis extends AbstractTest { long carryInAndOutWorkload = getCarryInAndOutWorkload(task, task.getWorkloadDistribution(), - new HashSet<>(), carryInAndOutInterval); + sortedSegments.get(task), carryInAndOutInterval); return carryInAndOutWorkload + bodyWorkload; } -- libgit2 0.26.0