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 long executeTime;
34 private int visited4time;
35 private int invokeNum;
37 // for building multicore codes
39 private int checkmask;
40 private boolean setmask;
42 //private boolean isolate;
43 //private Vector<ScheduleEdge> allys;
46 * Creates a new flagstate with all flags set to false.
47 * @param cd ClassDescriptor
49 public FlagState(ClassDescriptor cd) {
50 this.flagstate=new HashSet();
52 this.tags=new Hashtable<TagDescriptor,Integer>();
53 this.uid=FlagState.nodeid++;
54 this.issourcenode=false;
55 this.executeTime = -1;
56 this.visited4time = -1;
63 //this.isolate = true;
68 * Creates a new flagstate with flags set according to the HashSet.
69 * If the flag exists in the hashset, it's set to true else set to false.
70 * @param cd ClassDescriptor
71 * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
73 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
74 this.flagstate=flagstate;
77 this.uid=FlagState.nodeid++;
78 this.issourcenode=false;
79 this.executeTime = -1;
80 this.visited4time = -1;
88 public int getiuid() {
92 public boolean isSetmask() {
96 public void setSetmask(boolean setmask) {
97 this.setmask = setmask;
101 * @param fd FlagDescriptor
102 * @return true if the flagstate contains fd else false.
104 public boolean get(FlagDescriptor fd) {
105 return flagstate.contains(fd);
108 /** Checks if the flagstate is a source node.
109 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
112 public boolean isSourceNode() {
116 /** Sets the flagstate as a source node.
118 public void setAsSourceNode() {
121 this.tasks=new Vector();
125 public void addAllocatingTask(TaskDescriptor task) {
129 public Vector getAllocatingTasks() {
134 public String toString() {
135 return cd.toString()+getTextLabel();
138 /** @return Iterator over the flags in the flagstate.
141 public Iterator getFlags() {
142 return flagstate.iterator();
145 public int numFlags() {
146 return flagstate.size();
149 public FlagState[] setTag(TagDescriptor tag, boolean set) {
150 HashSet newset1=(HashSet)flagstate.clone();
151 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
155 if (tags.containsKey(tag))
156 count=tags.get(tag).intValue();
159 newtags1.put(tag, new Integer(count));
160 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
163 if (tags.containsKey(tag))
164 count=tags.get(tag).intValue();
165 newtags1.put(tag, new Integer(count));
166 if ((count+1)==KLIMIT)
167 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
169 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
173 public FlagState[] setTag(TagDescriptor tag) {
174 HashSet newset1=(HashSet)flagstate.clone();
175 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
177 if (tags.containsKey(tag)) {
178 //Code could try to remove flag that doesn't exist
180 switch (tags.get(tag).intValue()) {
182 newtags1.put(tag,new Integer(MULTITAGS));
183 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
186 return new FlagState[] {this};
192 newtags1.put(tag,new Integer(ONETAG));
193 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
197 public int getTagCount(TagDescriptor tag) {
198 if (tags.containsKey(tag))
199 return tags.get(tag).intValue();
203 public int getTagCount(String tagtype) {
204 return getTagCount(new TagDescriptor(tagtype));
207 public FlagState[] clearTag(TagDescriptor tag) {
208 if (tags.containsKey(tag)) {
209 switch(tags.get(tag).intValue()) {
211 HashSet newset=(HashSet)flagstate.clone();
212 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
214 return new FlagState[] {new FlagState(newset,cd,newtags)};
217 //two possibilities - count remains 2 or becomes 1
219 HashSet newset1=(HashSet)flagstate.clone();
220 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
223 HashSet newset2=(HashSet)flagstate.clone();
224 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
225 newtags1.put(tag,new Integer(ONETAG));
226 return new FlagState[] {new FlagState(newset1, cd, newtags2),
227 new FlagState(newset2, cd, newtags2)};
233 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
237 /** Creates a string description of the flagstate
238 * e.g. a flagstate with five flags could look like 01001
239 * @param flags an array of flagdescriptors.
240 * @return string representation of the flagstate.
242 public String toString(FlagDescriptor[] flags) {
243 StringBuffer sb = new StringBuffer(flagstate.size());
244 for(int i=0; i < flags.length; i++) {
251 return new String(sb);
255 * @return returns the classdescriptor of the flagstate.
258 public ClassDescriptor getClassDescriptor() {
262 /** Sets the status of a specific flag in a flagstate after cloning it.
263 * @param fd FlagDescriptor of the flag whose status is being set.
264 * @param status boolean value
265 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
268 public FlagState setFlag(FlagDescriptor fd, boolean status) {
269 HashSet newset=(HashSet) flagstate.clone();
270 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
273 else if (newset.contains(fd)) {
277 return new FlagState(newset, cd, newtags);
280 /** Tests for equality of two flagstate objects.
283 public boolean equals(Object o) {
284 if (o instanceof FlagState) {
285 FlagState fs=(FlagState)o;
288 if(fs.byObj != this.byObj) {
291 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
296 public int hashCode() {
297 return cd.hashCode()^flagstate.hashCode()^tags.hashCode()^byObj;
300 public String getLabel() {
304 public String getTextLabel() {
306 for(Iterator it=getFlags(); it.hasNext(); ) {
307 FlagDescriptor fd=(FlagDescriptor) it.next();
311 label+=", "+fd.toString();
313 for (Enumeration en_tags=getTags(); en_tags.hasMoreElements(); ) {
314 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
315 switch (tags.get(td).intValue()) {
318 label=td.toString()+"(1)";
320 label+=", "+td.toString()+"(1)";
325 label=td.toString()+"(n)";
327 label+=", "+td.toString()+"(n)";
339 public Enumeration getTags() {
343 public long getExeTime() {
345 if(this.executeTime == -1) {
346 if(this.visited4time == -1) {
347 this.visited4time = 0;
350 // visited, this node is in a loop
352 // currently set 10 as the largest time
353 this.executeTime = FlagState.MAXTIME;
356 } catch (Exception e) {
360 return this.executeTime;
363 public void setExeTime(long exeTime) {
364 this.executeTime = exeTime;
367 public int getAndmask() {
371 public void setAndmask(int andmask) {
372 this.andmask = andmask;
375 public int getCheckmask() {
379 public void setCheckmask(int checkmask) {
380 this.checkmask = checkmask;
383 public void calExeTime() throws Exception {
384 Iterator it = this.edges();
386 FEdge fe = (FEdge)it.next();
387 while((fe != null) && (fe.getTarget().equals(this))) {
389 fe = (FEdge)it.next();
395 this.executeTime = 0;
397 if(fe.getExeTime() == -1) {
398 throw new Exception("Error: Uninitiate FEdge!");
400 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
403 this.executeTime = 0;
405 while(it.hasNext()) {
406 FEdge fe = (FEdge)it.next();
407 long temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
408 if(temp < this.executeTime) {
409 this.executeTime = temp;
414 public Object clone() {
417 o = (FlagState) super.clone();
418 } catch(CloneNotSupportedException e) {
421 o.uid = FlagState.nodeid++;
422 o.edges = new Vector();
423 for(int i = 0; i < this.edges.size(); i++) {
424 o.edges.addElement(this.edges.elementAt(i));
426 o.inedges = new Vector();
427 for(int i = 0; i < this.inedges.size(); i++) {
428 o.inedges.addElement(this.inedges.elementAt(i));
430 o.byObj = this.byObj;
434 public void init4Simulate() {
438 public FEdge process(TaskDescriptor td) {
441 if(td.getSymbol().equals("addIYLM")) {
444 // refresh all the expInvokeNum of each edge
445 for(int i = 0; i < this.edges.size(); i++) {
446 next = (FEdge) this.edges.elementAt(i);
447 if(this.byObj == 0) {
448 next.setExpInvokeNum((int)(Math.ceil(this.invokeNum * next.getProbability() / 100)));
450 next.setExpInvokeNum((int)(Math.ceil(((this.invokeNum - 1) / this.byObj + 1) * next.getProbability() / 100)));
454 // find the one with the biggest gap between its actual invoke time and
455 // the expected invoke time and associated with task td
459 boolean isbackedge = true;
460 for(int i = 0; i < this.edges.size(); i++) {
461 next = ((FEdge) this.edges.elementAt(i));
462 int temp = (this.byObj == 0)?next.getInvokeNumGap():next.getInvokeNumGapByObj(this.byObj);
463 boolean exchange = false;
464 if((temp > gap) && (next.getTask().equals(td))) {
466 } else if(temp == gap) {
467 if(next.getProbability() > prob) {
469 } else if(next.getProbability() == prob) {
470 if(!isbackedge && next.isbackedge()) {
471 // backedge has higher priority
479 prob = next.getProbability();
480 isbackedge = next.isbackedge();
483 next = (FEdge) this.edges.elementAt(index);
489 public int getByObj() {
493 public void setByObj(int byObj) {
497 /*public Vector<ScheduleEdge> getAllys() {
501 public void addAlly(ScheduleEdge se) {
502 if(this.allys == null) {
503 assert(this.isolate == true);
504 this.isolate = false;
505 this.allys = new Vector<ScheduleEdge>();
507 this.allys.addElement(se);
510 public boolean isIsolate() {