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;
21 private static int nodeid=0;
23 private final HashSet flagstate;
24 private final ClassDescriptor cd;
25 private final Hashtable<TagDescriptor,Integer> tags;
26 private boolean issourcenode;
28 public static final int KLIMIT=2;
31 // for static scheduling
32 private int executeTime;
33 private int invokeNum;
34 // for building multicore codes
36 private int checkmask;
37 private boolean setmask;
39 //private boolean isolate;
40 //private Vector<ScheduleEdge> allys;
43 * Creates a new flagstate with all flags set to false.
44 * @param cd ClassDescriptor
46 public FlagState(ClassDescriptor cd) {
47 this.flagstate=new HashSet();
49 this.tags=new Hashtable<TagDescriptor,Integer>();
50 this.uid=FlagState.nodeid++;
51 this.issourcenode=false;
52 this.executeTime = -1;
58 //this.isolate = true;
63 * Creates a new flagstate with flags set according to the HashSet.
64 * If the flag exists in the hashset, it's set to true else set to false.
65 * @param cd ClassDescriptor
66 * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
68 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
69 this.flagstate=flagstate;
72 this.uid=FlagState.nodeid++;
73 this.issourcenode=false;
74 this.executeTime = -1;
82 public int getiuid() {
86 public boolean isSetmask() {
90 public void setSetmask(boolean setmask) {
91 this.setmask = setmask;
95 * @param fd FlagDescriptor
96 * @return true if the flagstate contains fd else false.
98 public boolean get(FlagDescriptor fd) {
99 return flagstate.contains(fd);
102 /** Checks if the flagstate is a source node.
103 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
106 public boolean isSourceNode(){
110 /** Sets the flagstate as a source node.
112 public void setAsSourceNode(){
115 this.tasks=new Vector();
119 public void addAllocatingTask(TaskDescriptor task){
123 public Vector getAllocatingTasks(){
128 public String toString() {
129 return cd.toString()+getTextLabel();
132 /** @return Iterator over the flags in the flagstate.
135 public Iterator getFlags() {
136 return flagstate.iterator();
139 public int numFlags(){
140 return flagstate.size();
143 public FlagState[] setTag(TagDescriptor tag, boolean set){
144 HashSet newset1=(HashSet)flagstate.clone();
145 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
149 if (tags.containsKey(tag))
150 count=tags.get(tag).intValue();
153 newtags1.put(tag, new Integer(count));
154 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
157 if (tags.containsKey(tag))
158 count=tags.get(tag).intValue();
159 newtags1.put(tag, new Integer(count));
160 if ((count+1)==KLIMIT)
161 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
163 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
167 public FlagState[] setTag(TagDescriptor tag){
168 HashSet newset1=(HashSet)flagstate.clone();
169 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
171 if (tags.containsKey(tag)){
172 //Code could try to remove flag that doesn't exist
174 switch (tags.get(tag).intValue()){
176 newtags1.put(tag,new Integer(MULTITAGS));
177 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
179 return new FlagState[] {this};
184 newtags1.put(tag,new Integer(ONETAG));
185 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
189 public int getTagCount(TagDescriptor tag) {
190 if (tags.containsKey(tag))
191 return tags.get(tag).intValue();
195 public int getTagCount(String tagtype){
196 return getTagCount(new TagDescriptor(tagtype));
199 public FlagState[] clearTag(TagDescriptor tag){
200 if (tags.containsKey(tag)){
201 switch(tags.get(tag).intValue()){
203 HashSet newset=(HashSet)flagstate.clone();
204 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
206 return new FlagState[]{new FlagState(newset,cd,newtags)};
209 //two possibilities - count remains 2 or becomes 1
211 HashSet newset1=(HashSet)flagstate.clone();
212 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
215 HashSet newset2=(HashSet)flagstate.clone();
216 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
217 newtags1.put(tag,new Integer(ONETAG));
218 return new FlagState[] {new FlagState(newset1, cd, newtags2),
219 new FlagState(newset2, cd, newtags2)};
224 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
228 /** Creates a string description of the flagstate
229 * e.g. a flagstate with five flags could look like 01001
230 * @param flags an array of flagdescriptors.
231 * @return string representation of the flagstate.
233 public String toString(FlagDescriptor[] flags)
235 StringBuffer sb = new StringBuffer(flagstate.size());
236 for(int i=0;i < flags.length; i++)
244 return new String(sb);
248 * @return returns the classdescriptor of the flagstate.
251 public ClassDescriptor getClassDescriptor(){
255 /** Sets the status of a specific flag in a flagstate after cloning it.
256 * @param fd FlagDescriptor of the flag whose status is being set.
257 * @param status boolean value
258 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
261 public FlagState setFlag(FlagDescriptor fd, boolean status) {
262 HashSet newset=(HashSet) flagstate.clone();
263 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
266 else if (newset.contains(fd)){
270 return new FlagState(newset, cd, newtags);
273 /** Tests for equality of two flagstate objects.
276 public boolean equals(Object o) {
277 if (o instanceof FlagState) {
278 FlagState fs=(FlagState)o;
281 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
286 public int hashCode() {
287 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
290 public String getLabel() {
294 public String getTextLabel() {
296 for(Iterator it=getFlags();it.hasNext();) {
297 FlagDescriptor fd=(FlagDescriptor) it.next();
301 label+=", "+fd.toString();
303 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
304 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
305 switch (tags.get(td).intValue()){
308 label=td.toString()+"(1)";
310 label+=", "+td.toString()+"(1)";
314 label=td.toString()+"(n)";
316 label+=", "+td.toString()+"(n)";
327 public Enumeration getTags(){
331 public int getExeTime() {
333 if(this.executeTime == -1) {
336 } catch (Exception e) {
340 return this.executeTime;
343 public void setExeTime(int exeTime) {
344 this.executeTime = exeTime;
347 public int getAndmask() {
351 public void setAndmask(int andmask) {
352 this.andmask = andmask;
355 public int getCheckmask() {
359 public void setCheckmask(int checkmask) {
360 this.checkmask = checkmask;
363 public void calExeTime() throws Exception {
364 Iterator it = this.edges();
366 FEdge fe = (FEdge)it.next();
367 while((fe != null) && (fe.getTarget().equals(this))) {
369 fe = (FEdge)it.next();
375 this.executeTime = 0;
377 if(fe.getExeTime() == -1) {
378 throw new Exception("Error: Uninitiate FEdge!");
380 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
383 this.executeTime = 0;
385 while(it.hasNext()) {
386 FEdge fe = (FEdge)it.next();
387 int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
388 if(temp < this.executeTime) {
389 this.executeTime = temp;
394 public Object clone() {
397 o = (FlagState)super.clone();
398 } catch(CloneNotSupportedException e){
401 o.uid = FlagState.nodeid++;
402 o.edges = new Vector();
403 for(int i = 0; i < this.edges.size(); i++) {
404 o.edges.addElement(this.edges.elementAt(i));
406 o.inedges = new Vector();
407 for(int i = 0; i < this.inedges.size(); i++) {
408 o.inedges.addElement(this.inedges.elementAt(i));
413 public void init4Simulate() {
417 public FEdge process(TaskDescriptor td) {
420 // refresh all the expInvokeNum of each edge
421 for(int i = 0; i < this.edges.size(); i++) {
422 next = (FEdge)this.edges.elementAt(i);
423 next.setExpInvokeNum((int)Math.round(this.invokeNum * (next.getProbability() / 100)));
426 // find the one with the biggest gap between its actual invoke time and the expected invoke time
427 // and associated with task td
430 for(int i = 0; i < this.edges.size(); i++) {
431 int temp = ((FEdge)this.edges.elementAt(index)).getInvokeNumGap();
432 if((temp > gap) && (next.getTask().equals(td))){
437 next = (FEdge)this.edges.elementAt(index);
443 /*public Vector<ScheduleEdge> getAllys() {
447 public void addAlly(ScheduleEdge se) {
448 if(this.allys == null) {
449 assert(this.isolate == true);
450 this.isolate = false;
451 this.allys = new Vector<ScheduleEdge>();
453 this.allys.addElement(se);
456 public boolean isIsolate() {