1 package Analysis.Scheduling;
3 import Analysis.TaskStateAnalysis.*;
9 /** This class holds flag transition diagram(s) can be put on one core.
11 public class ScheduleNode extends GraphNode implements Cloneable{
14 private static int nodeID=0;
16 private Vector<ClassNode> classNodes;
17 Vector<ScheduleEdge> scheduleEdges;
19 private int executionTime;
23 private Hashtable<ClassDescriptor, Vector<ScheduleNode>> targetSNodes;
24 private boolean sorted = false;
27 * @param cd ClassDescriptor
30 public ScheduleNode() {
31 this.uid=ScheduleNode.nodeID++;
33 this.executionTime = -1;
36 public ScheduleNode(ClassNode cn) {
37 this.uid=ScheduleNode.nodeID++;
39 this.classNodes = new Vector<ClassNode>();
40 this.scheduleEdges = new Vector<ScheduleEdge>();
41 this.classNodes.add(cn);
42 this.addEdge(cn.getEdgeVector());
43 this.executionTime = -1;
50 public int getCoreNum() {
54 public void setCoreNum(int coreNum) {
55 this.coreNum = coreNum;
58 public void addTargetSNode(ClassDescriptor cd, ScheduleNode sn) {
59 if(this.targetSNodes == null) {
60 this.targetSNodes = new Hashtable<ClassDescriptor, Vector<ScheduleNode>>();
63 if(!this.targetSNodes.containsKey(cd)) {
64 this.targetSNodes.put(cd, new Vector<ScheduleNode>());
66 this.targetSNodes.get(cd).add(sn);
69 public void listTasks() {
70 if(this.tasks == null) {
71 this.tasks = new Vector();
75 for(i = 0; i < classNodes.size(); i++) {
76 Iterator it_flags = classNodes.elementAt(i).getFlags();
77 while(it_flags.hasNext()) {
78 FlagState fs = (FlagState)it_flags.next();
79 Iterator it_edges = fs.edges();
80 while(it_edges.hasNext()) {
81 TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
82 if(!this.tasks.contains(td)) {
90 public void addTask(TaskDescriptor task){
94 public Vector getTasks(){
98 public boolean isSorted() {
102 public void setSorted(boolean sorted) {
103 this.sorted = sorted;
106 public String toString() {
107 String temp = new String("");
108 for(int i = 0; i < classNodes.size(); i++) {
109 temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
111 temp += getTextLabel();
115 public Vector getClassNodes() {
116 if(classNodes == null) {
117 classNodes = new Vector<ClassNode>();
122 public Iterator getClassNodesIterator() {
123 return classNodes.iterator();
126 public void resetClassNodes() {
130 public Vector getScheduleEdges() {
131 if(scheduleEdges == null) {
132 scheduleEdges = new Vector<ScheduleEdge>();
134 return scheduleEdges;
137 public Iterator getScheduleEdgesIterator() {
138 return scheduleEdges.iterator();
141 public void resetScheduleEdges() {
142 scheduleEdges = null;
145 public int getExeTime() {
146 if(this.executionTime == -1) {
149 } catch (Exception e) {
153 return this.executionTime;
156 public void calExeTime() throws Exception {
157 if(this.classNodes.size() != 1) {
158 throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
160 ClassNode cn = this.classNodes.elementAt(0);
162 throw new Error("Error: Non-sorted ClassNode!");
164 this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
167 /** Tests for equality of two flagstate objects.
170 public boolean equals(Object o) {
171 if (o instanceof ScheduleNode) {
172 ScheduleNode fs=(ScheduleNode)o;
173 if ((fs.getCoreNum() != this.coreNum) ||
174 (fs.sorted != this.sorted) ||
175 (fs.executionTime != this.executionTime)){
178 if(fs.tasks != null) {
179 if(!fs.tasks.equals(this.tasks)) {
182 } else if (tasks != null) {
185 if (fs.targetSNodes != null) {
186 if(!fs.targetSNodes.equals(this.targetSNodes)) {
189 } else if(this.targetSNodes != null) {
192 if(fs.classNodes != null) {
193 if(!fs.classNodes.equals(classNodes)) {
196 } else if(classNodes != null) {
199 return (fs.scheduleEdges.equals(scheduleEdges));
204 public int hashCode() {
205 return classNodes.hashCode()^scheduleEdges.hashCode();
208 public String getLabel() {
209 return "cluster" + uid;
212 public String getTextLabel() {
214 if(this.coreNum != -1) {
215 label = "Core " + this.coreNum;
223 public Object clone(Hashtable<ClassNode, ClassNode> cn2cn) {
224 ScheduleNode o = null;
226 o = (ScheduleNode)super.clone();
227 } catch(CloneNotSupportedException e){
230 o.uid = ScheduleNode.nodeID++;
231 // Clone all the internal ClassNodes and ScheduleEdges
232 Vector<ClassNode> tcns = new Vector<ClassNode>();
233 Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
235 for(i = 0; i < this.classNodes.size(); i++) {
236 ClassNode tcn = this.classNodes.elementAt(i);
237 ClassNode cn = (ClassNode)tcn.clone();
238 cn.setScheduleNode(o);
242 for(i = 0; i < this.scheduleEdges.size(); i++) {
243 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
244 ScheduleEdge se = null;
245 if(!temp.getIsNew()) {
246 se = new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false);
248 se = new ScheduleEdge(o, "new",temp.getClassDescriptor());
250 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
251 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
252 se.setProbability(temp.getProbability());
253 se.setNewRate(temp.getNewRate());
254 se.setTransTime(temp.getTransTime());
258 o.scheduleEdges = tses;
261 o.inedges = new Vector();
262 o.edges = new Vector();
267 public void mergeSEdge(ScheduleEdge se) {
268 assert(se.getIsNew());
270 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
271 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
273 for(int i = 0; i < targetCNodes.size(); i++) {
274 targetCNodes.elementAt(i).setScheduleNode(this);
277 if(classNodes == null) {
278 classNodes = targetCNodes;
279 scheduleEdges = targetSEdges;
281 if(targetCNodes.size() != 0) {
282 classNodes.addAll(targetCNodes);
284 if(targetSEdges.size() != 0) {
285 scheduleEdges.addAll(targetSEdges);
291 scheduleEdges.add(se);
292 se.resetListExeTime();
293 se.getTarget().removeInedge(se);
295 Iterator it_edges = se.getTarget().edges();
296 while(it_edges.hasNext()) {
297 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
299 this.edges.addElement(tse);
302 // As all tasks inside one ScheduleNode are executed sequentially,
303 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
304 if(this.executionTime == -1) {
305 this.executionTime = 0;
307 this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
310 public void mergeSNode(ScheduleNode sn) throws Exception {
311 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
312 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
314 for(int i = 0; i < targetCNodes.size(); i++) {
315 targetCNodes.elementAt(i).setScheduleNode(this);
318 if(classNodes == null) {
319 classNodes = targetCNodes;
320 scheduleEdges = targetSEdges;
322 if(targetCNodes.size() != 0) {
323 classNodes.addAll(targetCNodes);
325 if(targetSEdges.size() != 0) {
326 scheduleEdges.addAll(targetSEdges);
332 Iterator it_edges = sn.edges();
333 while(it_edges.hasNext()) {
334 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
336 this.edges.addElement(tse);
339 // As all tasks inside one ScheduleNode are executed sequentially,
340 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
341 if(this.executionTime == -1) {
342 throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
344 if(this.executionTime < sn.getExeTime()) {
345 this.executionTime = sn.getExeTime();