1 package Analysis.TaskStateAnalysis;
3 import Analysis.Scheduling.ScheduleEdge;
4 import Analysis.TaskStateAnalysis.*;
10 import Util.GraphNode;
12 /** This class is used to hold the flag states that a class in the Bristlecone
13 * program can exist in, during runtime.
15 public class FlagState extends GraphNode implements Cloneable {
16 public static final int ONETAG=1;
17 public static final int NOTAGS=0;
18 public static final int MULTITAGS=-1;
19 public static final int MAXTIME=10;
22 private static int nodeid=0;
24 private final HashSet flagstate;
25 private final ClassDescriptor cd;
26 private final Hashtable<TagDescriptor,Integer> tags;
27 private boolean issourcenode;
29 public static final int KLIMIT=2;
32 // for static scheduling
33 private int executeTime;
34 private int visited4time;
35 private int invokeNum;
36 // for building multicore codes
38 private int checkmask;
39 private boolean setmask;
41 //private boolean isolate;
42 //private Vector<ScheduleEdge> allys;
45 * Creates a new flagstate with all flags set to false.
46 * @param cd ClassDescriptor
48 public FlagState(ClassDescriptor cd) {
49 this.flagstate=new HashSet();
51 this.tags=new Hashtable<TagDescriptor,Integer>();
52 this.uid=FlagState.nodeid++;
53 this.issourcenode=false;
54 this.executeTime = -1;
55 this.visited4time = -1;
61 //this.isolate = true;
66 * Creates a new flagstate with flags set according to the HashSet.
67 * If the flag exists in the hashset, it's set to true else set to false.
68 * @param cd ClassDescriptor
69 * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
71 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
72 this.flagstate=flagstate;
75 this.uid=FlagState.nodeid++;
76 this.issourcenode=false;
77 this.executeTime = -1;
78 this.visited4time = -1;
86 public int getiuid() {
90 public boolean isSetmask() {
94 public void setSetmask(boolean setmask) {
95 this.setmask = setmask;
99 * @param fd FlagDescriptor
100 * @return true if the flagstate contains fd else false.
102 public boolean get(FlagDescriptor fd) {
103 return flagstate.contains(fd);
106 /** Checks if the flagstate is a source node.
107 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
110 public boolean isSourceNode() {
114 /** Sets the flagstate as a source node.
116 public void setAsSourceNode() {
119 this.tasks=new Vector();
123 public void addAllocatingTask(TaskDescriptor task) {
127 public Vector getAllocatingTasks() {
132 public String toString() {
133 return cd.toString()+getTextLabel();
136 /** @return Iterator over the flags in the flagstate.
139 public Iterator getFlags() {
140 return flagstate.iterator();
143 public int numFlags() {
144 return flagstate.size();
147 public FlagState[] setTag(TagDescriptor tag, boolean set) {
148 HashSet newset1=(HashSet)flagstate.clone();
149 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
153 if (tags.containsKey(tag))
154 count=tags.get(tag).intValue();
157 newtags1.put(tag, new Integer(count));
158 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
161 if (tags.containsKey(tag))
162 count=tags.get(tag).intValue();
163 newtags1.put(tag, new Integer(count));
164 if ((count+1)==KLIMIT)
165 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
167 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
171 public FlagState[] setTag(TagDescriptor tag) {
172 HashSet newset1=(HashSet)flagstate.clone();
173 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
175 if (tags.containsKey(tag)){
176 //Code could try to remove flag that doesn't exist
178 switch (tags.get(tag).intValue()){
180 newtags1.put(tag,new Integer(MULTITAGS));
181 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
184 return new FlagState[] {this};
190 newtags1.put(tag,new Integer(ONETAG));
191 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
195 public int getTagCount(TagDescriptor tag) {
196 if (tags.containsKey(tag))
197 return tags.get(tag).intValue();
201 public int getTagCount(String tagtype) {
202 return getTagCount(new TagDescriptor(tagtype));
205 public FlagState[] clearTag(TagDescriptor tag) {
206 if (tags.containsKey(tag)){
207 switch(tags.get(tag).intValue()){
209 HashSet newset=(HashSet)flagstate.clone();
210 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
212 return new FlagState[] {new FlagState(newset,cd,newtags)};
215 //two possibilities - count remains 2 or becomes 1
217 HashSet newset1=(HashSet)flagstate.clone();
218 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
221 HashSet newset2=(HashSet)flagstate.clone();
222 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
223 newtags1.put(tag,new Integer(ONETAG));
224 return new FlagState[] {new FlagState(newset1, cd, newtags2),
225 new FlagState(newset2, cd, newtags2)};
231 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
235 /** Creates a string description of the flagstate
236 * e.g. a flagstate with five flags could look like 01001
237 * @param flags an array of flagdescriptors.
238 * @return string representation of the flagstate.
240 public String toString(FlagDescriptor[] flags) {
241 StringBuffer sb = new StringBuffer(flagstate.size());
242 for(int i=0; i < flags.length; i++){
249 return new String(sb);
253 * @return returns the classdescriptor of the flagstate.
256 public ClassDescriptor getClassDescriptor() {
260 /** Sets the status of a specific flag in a flagstate after cloning it.
261 * @param fd FlagDescriptor of the flag whose status is being set.
262 * @param status boolean value
263 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
266 public FlagState setFlag(FlagDescriptor fd, boolean status) {
267 HashSet newset=(HashSet) flagstate.clone();
268 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
271 else if (newset.contains(fd)){
275 return new FlagState(newset, cd, newtags);
278 /** Tests for equality of two flagstate objects.
281 public boolean equals(Object o) {
282 if (o instanceof FlagState) {
283 FlagState fs=(FlagState)o;
286 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
291 public int hashCode() {
292 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
295 public String getLabel() {
299 public String getTextLabel() {
301 for(Iterator it=getFlags(); it.hasNext();) {
302 FlagDescriptor fd=(FlagDescriptor) it.next();
306 label+=", "+fd.toString();
308 for (Enumeration en_tags=getTags(); en_tags.hasMoreElements();){
309 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
310 switch (tags.get(td).intValue()){
313 label=td.toString()+"(1)";
315 label+=", "+td.toString()+"(1)";
320 label=td.toString()+"(n)";
322 label+=", "+td.toString()+"(n)";
334 public Enumeration getTags() {
338 public int getExeTime() {
340 if(this.executeTime == -1) {
341 if(this.visited4time == -1) {
342 this.visited4time = 0;
345 // visited, this node is in a loop
347 // currently set 10 as the largest time
348 this.executeTime = FlagState.MAXTIME;
351 } catch (Exception e) {
355 return this.executeTime;
358 public void setExeTime(int exeTime) {
359 this.executeTime = exeTime;
362 public int getAndmask() {
366 public void setAndmask(int andmask) {
367 this.andmask = andmask;
370 public int getCheckmask() {
374 public void setCheckmask(int checkmask) {
375 this.checkmask = checkmask;
378 public void calExeTime() throws Exception {
379 Iterator it = this.edges();
381 FEdge fe = (FEdge)it.next();
382 while((fe != null) && (fe.getTarget().equals(this))) {
384 fe = (FEdge)it.next();
390 this.executeTime = 0;
392 if(fe.getExeTime() == -1) {
393 throw new Exception("Error: Uninitiate FEdge!");
395 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
398 this.executeTime = 0;
400 while(it.hasNext()) {
401 FEdge fe = (FEdge)it.next();
402 int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
403 if(temp < this.executeTime) {
404 this.executeTime = temp;
409 public Object clone() {
412 o = (FlagState) super.clone();
413 } catch(CloneNotSupportedException e){
416 o.uid = FlagState.nodeid++;
417 o.edges = new Vector();
418 for(int i = 0; i < this.edges.size(); i++) {
419 o.edges.addElement(this.edges.elementAt(i));
421 o.inedges = new Vector();
422 for(int i = 0; i < this.inedges.size(); i++) {
423 o.inedges.addElement(this.inedges.elementAt(i));
428 public void init4Simulate() {
432 public FEdge process(TaskDescriptor td) {
435 // refresh all the expInvokeNum of each edge
436 for(int i = 0; i < this.edges.size(); i++) {
437 next = (FEdge) this.edges.elementAt(i);
438 next.setExpInvokeNum((int)Math.round(this.invokeNum * (next.getProbability() / 100)));
441 // find the one with the biggest gap between its actual invoke time and the expected invoke time
442 // and associated with task td
445 for(int i = 0; i < this.edges.size(); i++) {
446 int temp = ((FEdge) this.edges.elementAt(index)).getInvokeNumGap();
447 if((temp > gap) && (next.getTask().equals(td))){
452 next = (FEdge) this.edges.elementAt(index);
458 /*public Vector<ScheduleEdge> getAllys() {
462 public void addAlly(ScheduleEdge se) {
463 if(this.allys == null) {
464 assert(this.isolate == true);
465 this.isolate = false;
466 this.allys = new Vector<ScheduleEdge>();
468 this.allys.addElement(se);
471 public boolean isIsolate() {