package Analysis.Scheduling;
import Analysis.TaskStateAnalysis.*;
+import Analysis.TaskStateAnalysis.FEdge.NewObjInfo;
import IR.*;
+
import java.util.*;
import java.io.*;
State state;
Vector<ScheduleNode> scheduleNodes;
Vector<ClassNode> classNodes;
+ Hashtable<ClassDescriptor, ClassNode> cd2ClassNode;
boolean sorted = false;
Vector<ScheduleEdge> scheduleEdges;
- Hashtable<TaskDescriptor, Hashtable<ClassDescriptor, Vector<ScheduleEdge>>> taskToSEdges;
-
- int probabilityThreshold;
+
+ int transThreshold;
public ScheduleAnalysis(State state, TaskAnalysis taskanalysis) {
this.state = state;
this.scheduleNodes = new Vector<ScheduleNode>();
this.classNodes = new Vector<ClassNode>();
this.scheduleEdges = new Vector<ScheduleEdge>();
- this.taskToSEdges = new Hashtable<TaskDescriptor, Hashtable<ClassDescriptor, Vector<ScheduleEdge>>>();
- this.probabilityThreshold = 45;
+ this.cd2ClassNode = new Hashtable<ClassDescriptor, ClassNode>();
+
+ this.transThreshold = 45;
}
- public void setProbabilityThreshold(int pt) {
- this.probabilityThreshold = pt;
- }
-
- public Vector<ScheduleEdge> getSEdges(TaskDescriptor td, ClassDescriptor cd) {
- return taskToSEdges.get(td).get(cd);
+ public void setTransThreshold(int tt) {
+ this.transThreshold = tt;
}
public Vector<ScheduleEdge> getSEdges4Test() {
ClassNode cNode = new ClassNode(cd, sFStates);
cNode.setSorted(true);
classNodes.add(cNode);
+ cd2ClassNode.put(cd, cNode);
cdToCNodes.put(cd, cNode);
- }
+ cNode.calExeTime();
+
+ // for test
+ if(cd.getSymbol().equals("C")) {
+ cNode.setTransTime(45);
+ }
+ }
}
// For each ClassNode create a ScheduleNode containing it
ScheduleNode sn = new ScheduleNode(classNodes.elementAt(i));
classNodes.elementAt(i).setScheduleNode(sn);
scheduleNodes.add(sn);
+ try {
+ sn.calExeTime();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
// Create 'new' edges between the ScheduleNodes.
ScheduleNode sNode = cNode.getScheduleNode();
for(int j = 0; j < numEdges; j++) {
FEdge pfe = fev.elementAt(j);
+ FEdge.NewObjInfo noi = pfe.getNewObjInfo(cd);
+ if ((noi == null) || (noi.getNewRate() == 0) || (noi.getProbability() == 0)) {
+ // fake creating edge, do not need to create corresponding 'new' edge
+ continue;
+ }
FlagState pfs = (FlagState)pfe.getTarget();
ClassDescriptor pcd = pfs.getClassDescriptor();
ClassNode pcNode = cdToCNodes.get(pcd);
-
- ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", td, cd);
+
+ ScheduleEdge sEdge = new ScheduleEdge(sNode, "new",/* td,*/ cd);
sEdge.setFEdge(pfe);
sEdge.setSourceCNode(pcNode);
sEdge.setTargetCNode(cNode);
sEdge.setTargetFState(root);
+ sEdge.setNewRate(noi.getNewRate());
+ sEdge.setProbability(noi.getProbability());
pcNode.getScheduleNode().addEdge(sEdge);
scheduleEdges.add(sEdge);
- if(taskToSEdges.get(td) == null) {
- taskToSEdges.put(td, new Hashtable<ClassDescriptor, Vector<ScheduleEdge>>());
- }
- if(taskToSEdges.get(td).get(cd) == null) {
- taskToSEdges.get(td).put(cd, new Vector<ScheduleEdge>());
- }
- taskToSEdges.get(td).get(cd).add(sEdge);
if((j !=0 ) || (k != 0) || (h != 0)) {
toBreakDown.add(sEdge);
}
for(i = 0; i < toBreakDown.size(); i++ ) {
cloneSNodeList(toBreakDown.elementAt(i), false);
}
+
+ // Remove fake 'new' edges
+ for(i = 0; i < scheduleEdges.size(); i++) {
+ ScheduleEdge se = scheduleEdges.elementAt(i);
+ if((0 == se.getNewRate()) || (0 == se.getProbability())) {
+ scheduleEdges.removeElement(se);
+ scheduleNodes.removeElement(se.getTarget());
+ }
+ }
}
+ /*private void removeSNodeList(ScheduleEdge se) {
+ ScheduleNode sNode = (ScheduleNode)se.getTarget();
+ scheduleNodes.removeElement(sNode);
+ Vector<ClassNode> cNodes = sNode.getClassNodes();
+ for(int i = 0; i < cNodes.size(); i++) {
+ classNodes.removeElement(cNodes.elementAt(i));
+ cd2ClassNode.remove(cNodes.elementAt(i).getClassDescriptor());
+ }
+ Vector<ScheduleEdge> edges = sNode.getEdgeVector();
+ for(int j = 0; j < edges.size(); j++) {
+ removeSNodeList(edges.elementAt(j));
+ }
+ }*/
+
public void scheduleAnalysis() {
// First iteration
- int i = 0;
- Vector<ScheduleEdge> rsev = new Vector<ScheduleEdge>();
+ int i = 0;
+ //Access the ScheduleEdges in reverse topology order
+ Hashtable<FEdge, Vector<ScheduleEdge>> fe2ses = new Hashtable<FEdge, Vector<ScheduleEdge>>();
+ Hashtable<ScheduleNode, Vector<FEdge>> sn2fes = new Hashtable<ScheduleNode, Vector<FEdge>>();
+ ScheduleNode preSNode = null;
for(i = scheduleEdges.size(); i > 0; i--) {
ScheduleEdge se = scheduleEdges.elementAt(i-1);
- if(!(se.getProbability() > this.probabilityThreshold)){
- // Merge the target ScheduleNode into the source ScheduleNode
- ((ScheduleNode)se.getSource()).merge(se);
- scheduleNodes.remove(se.getTarget());
- se.setTarget((ScheduleNode)se.getSource());
- rsev.add(se);
+ if(preSNode == null) {
+ preSNode = (ScheduleNode)se.getSource();
+ }
+ if(se.getIsNew()) {
+ boolean split = false;
+ FEdge fe = se.getFEdge();
+ if(fe.getSource() == fe.getTarget()) {
+ // back edge
+ int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+ int rate = 0;
+ if(repeat > 1){
+ for(int j = 1; j< repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(1);
+ se.setProbability(100);
+ }
+ try {
+ rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ for(int j = rate - 1; j > 0; j--) {
+ for(int k = repeat; k > 0; k--) {
+ cloneSNodeList(se, true);
+ }
+ }
+ } else {
+ // if preSNode is not the same as se's source ScheduleNode
+ // handle any ScheduleEdges previously put into fe2ses whose source ScheduleNode is preSNode
+ boolean same = (preSNode == se.getSource());
+ if(!same) {
+ if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) {
+ if(sn2fes.containsKey(preSNode)) {
+ Vector<FEdge> fes = sn2fes.remove(preSNode);
+ for(int j = 0; j < fes.size(); j++) {
+ FEdge tempfe = fes.elementAt(j);
+ Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+ ScheduleEdge tempse = ses.elementAt(0);
+ int temptime = tempse.getListExeTime();
+ // find out the ScheduleEdge with least exeTime
+ for(int k = 1; k < ses.size(); k++) {
+ int ttemp = ses.elementAt(k).getListExeTime();
+ if(ttemp < temptime) {
+ tempse = ses.elementAt(k);
+ temptime = ttemp;
+ }
+ }
+ // handle the tempse
+ handleScheduleEdge(tempse, true);
+ ses.removeElement(tempse);
+ // handle other ScheduleEdges
+ for(int k = 0; k < ses.size(); k++) {
+ handleScheduleEdge(ses.elementAt(k), false);
+ }
+ ses = null;
+ fe2ses.remove(tempfe);
+ }
+ fes = null;
+ }
+ }
+ preSNode = (ScheduleNode)se.getSource();
+ }
+
+ // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'nmew' edges
+ // associated with a last task inside this ClassNode
+ if(!fe.getTarget().edges().hasNext()) {
+ if(fe2ses.get(fe) == null) {
+ fe2ses.put(fe, new Vector<ScheduleEdge>());
+ }
+ if(sn2fes.get((ScheduleNode)se.getSource()) == null) {
+ sn2fes.put((ScheduleNode)se.getSource(), new Vector<FEdge>());
+ }
+ fe2ses.get(fe).add(se);
+ sn2fes.get((ScheduleNode)se.getSource()).add(fe);
+ } else {
+ // As this is not a last task, first handle available ScheduleEdges previously put into fe2ses
+ if((same) && (sn2fes.containsKey(preSNode))) {
+ Vector<FEdge> fes = sn2fes.remove(preSNode);
+ for(int j = 0; j < fes.size(); j++) {
+ FEdge tempfe = fes.elementAt(j);
+ Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+ ScheduleEdge tempse = ses.elementAt(0);
+ int temptime = tempse.getListExeTime();
+ // find out the ScheduleEdge with least exeTime
+ for(int k = 1; k < ses.size(); k++) {
+ int ttemp = ses.elementAt(k).getListExeTime();
+ if(ttemp < temptime) {
+ tempse = ses.elementAt(k);
+ temptime = ttemp;
+ }
+ }
+ // handle the tempse
+ handleScheduleEdge(tempse, true);
+ ses.removeElement(tempse);
+ // handle other ScheduleEdges
+ for(int k = 0; k < ses.size(); k++) {
+ handleScheduleEdge(ses.elementAt(k), false);
+ }
+ ses = null;
+ fe2ses.remove(tempfe);
+ }
+ fes = null;
+ }
+
+ if((!(se.getTransTime() < this.transThreshold)) && (se.getSourceCNode().getTransTime() < se.getTransTime())) {
+ split = true;
+ splitSNode(se, true);
+ } else {
+ // handle this ScheduleEdge
+ handleScheduleEdge(se, true);
+ }
+ }
+ }
}
}
- scheduleEdges.removeAll(rsev);
- rsev = null;
-
- //Second iteration
- //Access the ScheduleEdges in reverse topology order
- for(i = scheduleEdges.size(); i > 0; i--) {
- ScheduleEdge se = scheduleEdges.elementAt(i-1);
- FEdge fe = se.getFEdge();
- if(fe.getSource() == fe.getTarget()) {
- // back edge
- if(se.getNewRate() > 1){
- for(int j = 1; j< se.getNewRate(); j++ ) {
- cloneSNodeList(se, true);
- }
- se.setNewRate(1);
+ if(!fe2ses.isEmpty()) {
+ Set<FEdge> keys = fe2ses.keySet();
+ Iterator it_keys = keys.iterator();
+ while(it_keys.hasNext()) {
+ FEdge tempfe = (FEdge)it_keys.next();
+ Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+ ScheduleEdge tempse = ses.elementAt(0);
+ int temptime = tempse.getListExeTime();
+ // find out the ScheduleEdge with least exeTime
+ for(int k = 1; k < ses.size(); k++) {
+ int ttemp = ses.elementAt(k).getListExeTime();
+ if(ttemp < temptime) {
+ tempse = ses.elementAt(k);
+ temptime = ttemp;
+ }
}
+ // handle the tempse
+ handleScheduleEdge(tempse, true);
+ ses.removeElement(tempse);
+ // handle other ScheduleEdges
+ for(int k = 0; k < ses.size(); k++) {
+ handleScheduleEdge(ses.elementAt(k), false);
+ }
+ ses = null;
+ }
+ keys = null;
+ fe2ses.clear();
+ sn2fes.clear();
+ }
+ }
+
+ private void handleScheduleEdge(ScheduleEdge se, boolean merge) {
+ int rate = 0;
+ int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+ if(merge) {
+ try {
+ rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime());
+ if(rate < 0 ) {
+ rate = 0;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if(0 == rate) {
+ // clone the whole ScheduleNode lists starting with se's target
+ for(int j = 1; j < repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(1);
+ se.setProbability(100);
} else {
- if(se.getNewRate() > 1){
+ repeat -= rate;
+ if(repeat > 0){
// clone the whole ScheduleNode lists starting with se's target
- for(int j = 1; j < se.getNewRate(); j++ ) {
+ for(int j = 0; j < repeat; j++ ) {
cloneSNodeList(se, true);
}
- se.setNewRate(1);
- } else if (se.getNewRate() == 1) {
- //merge the target ScheduleNode to the source ScheduleNode
- ((ScheduleNode)se.getSource()).merge(se);
- scheduleNodes.remove(se.getTarget());
- scheduleEdges.removeElement(se);
- se.setTarget((ScheduleNode)se.getSource());
- }
+ se.setNewRate(rate);
+ se.setProbability(100);
+ }
}
- }
+ // merge the original ScheduleNode to the source ScheduleNode
+ ((ScheduleNode)se.getSource()).mergeSEdge(se);
+ scheduleNodes.remove(se.getTarget());
+ scheduleEdges.removeElement(se);
+ // As se has been changed into an internal edge inside a ScheduleNode,
+ // change the source and target of se from original ScheduleNodes into ClassNodes.
+ se.setTarget(se.getTargetCNode());
+ se.setSource(se.getSourceCNode());
+ } else {
+ // clone the whole ScheduleNode lists starting with se's target
+ for(int j = 1; j < repeat; j++ ) {
+ cloneSNodeList(se, true);
+ }
+ se.setNewRate(1);
+ se.setProbability(100);
+ }
}
private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) {
Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn);
scheduleNodes.add(csNode);
-
+
// Clone all the external in ScheduleEdges
int i;
if(copyIE) {
Vector inedges = sEdge.getTarget().getInedgeVector();
for(i = 0; i < inedges.size(); i++) {
ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
- ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getTask(), tse.getClassDescriptor());
- se.setProbability(tse.getProbability());
- se.setNewRate(1);
- se.setFEdge(tse.getFEdge());
+ ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getClassDescriptor(), tse.getIsNew());
+ if(tse.getIsNew()) {
+ //se.setProbability(tse.getProbability());
+ se.setProbability(100);
+ se.setNewRate(1);
+ se.setFEdge(tse.getFEdge());
+ }
se.setSourceCNode(tse.getSourceCNode());
se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
tse.getSource().addEdge(se);
sEdge.setTarget(csNode);
csNode.getInedgeVector().add(sEdge);
sEdge.setTargetCNode(cn2cn.get(sEdge.getTargetCNode()));
+ sEdge.setTargetFState(null);
}
Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>();
clone.add(tSNode);
toClone.add((ScheduleNode)tse.getTarget());
qcn2cn.add(tocn2cn);
- ScheduleEdge se = new ScheduleEdge(tSNode, "new", tse.getTask(), tse.getClassDescriptor());
- se.setProbability(tse.getProbability());
- se.setNewRate(tse.getNewRate());
+ ScheduleEdge se = null;
+ if(tse.getIsNew()) {
+ se = new ScheduleEdge(tSNode, "new", tse.getClassDescriptor(), tse.getIsNew());
+ se.setProbability(tse.getProbability());
+ se.setNewRate(tse.getNewRate());
+ } else {
+ se = new ScheduleEdge(tSNode, "transmit", tse.getClassDescriptor(), false);
+ }
se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
csNode.addEdge(se);
}
}
+ private int calInExeTime(FlagState fs) throws Exception {
+ int exeTime = 0;
+ ClassDescriptor cd = fs.getClassDescriptor();
+ ClassNode cNode = cd2ClassNode.get(cd);
+ exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime();
+ while(true) {
+ Vector inedges = cNode.getInedgeVector();
+ if(inedges.size() > 1) {
+ throw new Exception("Error: ClassNode's inedges more than one!");
+ }
+ if(inedges.size() > 0) {
+ ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0);
+ cNode = (ClassNode)sEdge.getSource();
+ exeTime += cNode.getFlagStates().elementAt(0).getExeTime();
+ }else {
+ break;
+ }
+ }
+ exeTime = cNode.getScheduleNode().getExeTime() - exeTime;
+ return exeTime;
+ }
+
+ private ScheduleNode splitSNode(ScheduleEdge se, boolean copy) {
+ FEdge fe = se.getFEdge();
+ FlagState fs = (FlagState)fe.getTarget();
+ FlagState nfs = (FlagState)fs.clone();
+ fs.getEdgeVector().removeAllElements();
+ nfs.getInedgeVector().removeAllElements();
+ ClassNode sCNode = se.getSourceCNode();
+
+ // split the subtree whose root is nfs from the whole flag transition tree
+ Vector<FlagState> sfss = sCNode.getFlagStates();
+ Vector<FlagState> fStates = new Vector<FlagState>();
+ Queue<FlagState> toiterate = new LinkedList<FlagState>();
+ toiterate.add(nfs);
+ fStates.add(nfs);
+ while(!toiterate.isEmpty()){
+ FlagState tfs = toiterate.poll();
+ Iterator it_edges = tfs.edges();
+ while(it_edges.hasNext()) {
+ FlagState temp = (FlagState)((FEdge)it_edges.next()).getTarget();
+ if(!fStates.contains(temp)) {
+ fStates.add(temp);
+ toiterate.add(temp);
+ sfss.removeElement(temp);
+ }
+ }
+ }
+ Vector<FlagState> sFStates = FlagState.DFS.topology(fStates, null);
+ // create a ClassNode and ScheduleNode for this subtree
+ ClassNode cNode = new ClassNode(sCNode.getClassDescriptor(), sFStates);
+ ScheduleNode sNode = new ScheduleNode(cNode);
+ cNode.setScheduleNode(sNode);
+ cNode.setSorted(true);
+ cNode.setTransTime(sCNode.getTransTime());
+ classNodes.add(cNode);
+ scheduleNodes.add(sNode);
+ try {
+ sNode.calExeTime();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ // flush the exeTime of fs and its ancestors
+ fs.setExeTime(0);
+ toiterate.add(fs);
+ while(!toiterate.isEmpty()) {
+ FlagState tfs = toiterate.poll();
+ int ttime = tfs.getExeTime();
+ Iterator it_inedges = tfs.inedges();
+ while(it_inedges.hasNext()) {
+ FEdge fEdge = (FEdge)it_inedges.next();
+ FlagState temp = (FlagState)fEdge.getSource();
+ int time = fEdge.getExeTime() + ttime;
+ if(temp.getExeTime() > time) {
+ temp.setExeTime(time);
+ toiterate.add(temp);
+ }
+ }
+ }
+
+
+ // create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode
+ ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false);
+ sEdge.setTargetFState(fs);
+ sEdge.setFEdge(fe);
+ sEdge.setSourceCNode(sCNode);
+ sEdge.setTargetCNode(cNode);
+ sEdge.setTargetFState(nfs);
+ // todo
+ // Add calculation codes for calculating transmit time of an object
+ sEdge.setTransTime(cNode.getTransTime());
+ se.getSource().addEdge(sEdge);
+ scheduleEdges.add(sEdge);
+ // redirect ScheudleEdges out of this subtree to the new ScheduleNode
+ Iterator it_sEdges = se.getSource().edges();
+ Vector<ScheduleEdge> toremove = new Vector<ScheduleEdge>();
+ while(it_sEdges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_sEdges.next();
+ if((tse != se) && (tse != sEdge) && (tse.getSourceCNode() == sCNode)) {
+ if((tse.getSourceFState() != fs) && (sFStates.contains(tse.getSourceFState()))) {
+ tse.setSource(sNode);
+ tse.setSourceCNode(cNode);
+ sNode.getEdgeVector().addElement(tse);
+ toremove.add(tse);
+ }
+ }
+ }
+ se.getSource().getEdgeVector().removeAll(toremove);
+
+ if(!copy) {
+ //merge se into its source ScheduleNode
+ ((ScheduleNode)se.getSource()).mergeSEdge(se);
+ scheduleNodes.remove(se.getTarget());
+ scheduleEdges.removeElement(se);
+ // As se has been changed into an internal edge inside a ScheduleNode,
+ // change the source and target of se from original ScheduleNodes into ClassNodes.
+ se.setTarget(se.getTargetCNode());
+ se.setSource(se.getSourceCNode());
+ } else {
+ handleScheduleEdge(se, true);
+ }
+
+ return sNode;
+ }
+
public void schedule() {
// Assign a core to each ScheduleNode
int i = 0;
output.println("\tsubgraph " + gn.getLabel() + "{");
output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
Iterator it_cnodes = gn.getClassNodesIterator();
- if(gn.isclone()) {
- while (it_cnodes.hasNext()) {
- ClassNode cn = (ClassNode) it_cnodes.next();
- output.println("\t\t" + cn.getLabel() + " [style=dashed, label=\"" + cn.getTextLabel() + "\", shape=box];");
- }
- } else {
- traverseCNodes(output, it_cnodes);
- }
+ traverseCNodes(output, it_cnodes);
//Draw the internal 'new' edges
Iterator it_edges =gn.getScheduleEdgesIterator();
while(it_edges.hasNext()) {
while(edges.hasNext()) {
ScheduleEdge se = (ScheduleEdge)edges.next();
output.print("\t");
- if(((ScheduleNode)se.getSource()).isclone()) {
+ if(se.getSourceFState() == null) {
output.print(se.getSourceCNode().getLabel());
} else {
output.print(se.getSourceFState().getLabel());
}
output.print(" -> ");
- if(((ScheduleNode)se.getTarget()).isclone()) {
- output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
+ if(se.getTargetFState() == null) {
+ output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]");
} else {
- output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed, ltail=" + gn.getLabel() + "];");
+ output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]");
}
}
}
//Draw clusters representing ClassNodes
while (it.hasNext()) {
ClassNode gn = (ClassNode) it.next();
- output.println("\tsubgraph " + gn.getClusterLabel() + "{");
- output.println("\t\tstyle=dashed;");
- output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
- traverseFlagStates(output, gn.getFlagStates());
- output.println("\t}\n");
+ if(gn.isclone()) {
+ output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
+ } else {
+ output.println("\tsubgraph " + gn.getClusterLabel() + "{");
+ output.println("\t\tstyle=dashed;");
+ output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
+ traverseFlagStates(output, gn.getFlagStates());
+ output.println("\t}\n");
+ }
}
}
Namer name=(Namer) namers.get(i);
String newlabel=name.nodeLabel(gn);
String newparams=name.nodeOption(gn);
-
+
if (!newlabel.equals("") && !label.equals("")) {
label+=", ";
}
}
label+=name.nodeLabel(gn);
}
+ label += ":[" + ((FlagState)gn).getExeTime() + "]";
if (!gn.merge)
output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
if (!newoption.equals(""))
edgedotnodeparams+=", "+newoption;
}
-
+ edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
+ Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
+ if(hashtable != null) {
+ Set<ClassDescriptor> keys = hashtable.keySet();
+ Iterator it_keys = keys.iterator();
+ while(it_keys.hasNext()) {
+ ClassDescriptor cd = (ClassDescriptor)it_keys.next();
+ NewObjInfo noi = hashtable.get(cd);
+ edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
+ }
+ }
output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
}
}
private int uid;
private static int nodeID=0;
+ private Vector<ClassNode> classNodes;
+ Vector<ScheduleEdge> scheduleEdges;
+
+ private int executionTime;
+
private int coreNum;
private Vector tasks;
private Hashtable<ClassDescriptor, Vector<ScheduleNode>> targetSNodes;
private boolean sorted = false;
-
- private boolean clone = false;
-
- private Vector<ClassNode> classNodes;
- Vector<ScheduleEdge> scheduleEdges;
/** Class constructor
* @param cd ClassDescriptor
public ScheduleNode() {
this.uid=ScheduleNode.nodeID++;
this.coreNum = -1;
+ this.executionTime = -1;
}
public ScheduleNode(ClassNode cn) {
this.scheduleEdges = new Vector<ScheduleEdge>();
this.classNodes.add(cn);
this.addEdge(cn.getEdgeVector());
+ this.executionTime = -1;
}
public int getuid() {
this.sorted = sorted;
}
- public boolean isclone() {
- return clone;
- }
-
public String toString() {
String temp = new String("");
for(int i = 0; i < classNodes.size(); i++) {
temp += getTextLabel();
return temp;
}
-
+
public Vector getClassNodes() {
if(classNodes == null) {
classNodes = new Vector<ClassNode>();
scheduleEdges = null;
}
+ public int getExeTime() {
+ if(this.executionTime == -1) {
+ try {
+ calExeTime();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return this.executionTime;
+ }
+
+ public void calExeTime() throws Exception {
+ if(this.classNodes.size() != 1) {
+ throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
+ }
+ ClassNode cn = this.classNodes.elementAt(0);
+ if(!cn.isSorted()) {
+ throw new Error("Error: Non-sorted ClassNode!");
+ }
+ this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
+ }
+
/** Tests for equality of two flagstate objects.
*/
ScheduleNode fs=(ScheduleNode)o;
if ((fs.getCoreNum() != this.coreNum) ||
(fs.sorted != this.sorted) ||
- (fs.clone != this.clone)){
+ (fs.executionTime != this.executionTime)){
return false;
}
if(fs.tasks != null) {
}
for(i = 0; i < this.scheduleEdges.size(); i++) {
ScheduleEdge temp = this.scheduleEdges.elementAt(i);
- ScheduleEdge se = new ScheduleEdge(o, "new", temp.getTask(), temp.getClassDescriptor());
+ ScheduleEdge se = null;
+ if(!temp.getIsNew()) {
+ se = new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false);
+ } else {
+ se = new ScheduleEdge(o, "new",temp.getClassDescriptor());
+ }
se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+ se.setProbability(temp.getProbability());
+ se.setNewRate(temp.getNewRate());
+ se.setTransTime(temp.getTransTime());
tses.add(se);
}
o.classNodes = tcns;
tses = null;
o.inedges = new Vector();
o.edges = new Vector();
-
- o.clone = true;
+
return o;
}
- public void merge(ScheduleEdge se) {
+ public void mergeSEdge(ScheduleEdge se) {
+ assert(se.getIsNew());
+
Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
targetSEdges = null;
scheduleEdges.add(se);
+ se.resetListExeTime();
se.getTarget().removeInedge(se);
this.removeEdge(se);
- //this.addEdge(se.getTarget().getEdgeVector());
Iterator it_edges = se.getTarget().edges();
while(it_edges.hasNext()) {
ScheduleEdge tse = (ScheduleEdge)it_edges.next();
tse.setSource(this);
this.edges.addElement(tse);
+ }
+
+ // As all tasks inside one ScheduleNode are executed sequentially,
+ // simply add the execution time of all the ClassNodes inside one ScheduleNode.
+ if(this.executionTime == -1) {
+ this.executionTime = 0;
+ }
+ this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
+ }
+
+ public void mergeSNode(ScheduleNode sn) throws Exception {
+ Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
+ Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
+
+ for(int i = 0; i < targetCNodes.size(); i++) {
+ targetCNodes.elementAt(i).setScheduleNode(this);
+ }
+
+ if(classNodes == null) {
+ classNodes = targetCNodes;
+ scheduleEdges = targetSEdges;
+ } else {
+ if(targetCNodes.size() != 0) {
+ classNodes.addAll(targetCNodes);
+ }
+ if(targetSEdges.size() != 0) {
+ scheduleEdges.addAll(targetSEdges);
+ }
+ }
+ targetCNodes = null;
+ targetSEdges = null;
+
+ Iterator it_edges = sn.edges();
+ while(it_edges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+ tse.setSource(this);
+ this.edges.addElement(tse);
+ }
+
+ // As all tasks inside one ScheduleNode are executed sequentially,
+ // simply add the execution time of all the ClassNodes inside one ScheduleNode.
+ if(this.executionTime == -1) {
+ throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
+ }
+ if(this.executionTime < sn.getExeTime()) {
+ this.executionTime = sn.getExeTime();
}
}
}