1 package Analysis.TaskStateAnalysis;
3 import Analysis.TaskStateAnalysis.*;
11 /** This class is used to hold the flag states that a class in the Bristlecone
12 * program can exist in, during runtime.
14 public class FlagState extends GraphNode implements Cloneable {
15 public static final int ONETAG=1;
16 public static final int NOTAGS=0;
17 public static final int MULTITAGS=-1;
20 private static int nodeid=0;
22 private final HashSet flagstate;
23 private final ClassDescriptor cd;
24 private final Hashtable<TagDescriptor,Integer> tags;
25 private boolean issourcenode;
27 public static final int KLIMIT=2;
30 private int executeTime;
31 private int invokeNum;
32 // for building multicore codes
34 private int checkmask;
35 private boolean setmask;
39 * Creates a new flagstate with all flags set to false.
40 * @param cd ClassDescriptor
42 public FlagState(ClassDescriptor cd) {
43 this.flagstate=new HashSet();
45 this.tags=new Hashtable<TagDescriptor,Integer>();
46 this.uid=FlagState.nodeid++;
47 this.issourcenode=false;
48 this.executeTime = -1;
57 * Creates a new flagstate with flags set according to the HashSet.
58 * If the flag exists in the hashset, it's set to true else set to false.
59 * @param cd ClassDescriptor
60 * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
62 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
63 this.flagstate=flagstate;
66 this.uid=FlagState.nodeid++;
67 this.issourcenode=false;
68 this.executeTime = -1;
76 public int getiuid() {
80 public boolean isSetmask() {
84 public void setSetmask(boolean setmask) {
85 this.setmask = setmask;
89 * @param fd FlagDescriptor
90 * @return true if the flagstate contains fd else false.
92 public boolean get(FlagDescriptor fd) {
93 return flagstate.contains(fd);
96 /** Checks if the flagstate is a source node.
97 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
100 public boolean isSourceNode(){
104 /** Sets the flagstate as a source node.
106 public void setAsSourceNode(){
109 this.tasks=new Vector();
113 public void addAllocatingTask(TaskDescriptor task){
117 public Vector getAllocatingTasks(){
122 public String toString() {
123 return cd.toString()+getTextLabel();
126 /** @return Iterator over the flags in the flagstate.
129 public Iterator getFlags() {
130 return flagstate.iterator();
133 public int numFlags(){
134 return flagstate.size();
137 public FlagState[] setTag(TagDescriptor tag, boolean set){
138 HashSet newset1=(HashSet)flagstate.clone();
139 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
143 if (tags.containsKey(tag))
144 count=tags.get(tag).intValue();
147 newtags1.put(tag, new Integer(count));
148 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
151 if (tags.containsKey(tag))
152 count=tags.get(tag).intValue();
153 newtags1.put(tag, new Integer(count));
154 if ((count+1)==KLIMIT)
155 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
157 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
161 public FlagState[] setTag(TagDescriptor tag){
162 HashSet newset1=(HashSet)flagstate.clone();
163 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
165 if (tags.containsKey(tag)){
166 //Code could try to remove flag that doesn't exist
168 switch (tags.get(tag).intValue()){
170 newtags1.put(tag,new Integer(MULTITAGS));
171 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
173 return new FlagState[] {this};
178 newtags1.put(tag,new Integer(ONETAG));
179 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
183 public int getTagCount(TagDescriptor tag) {
184 if (tags.containsKey(tag))
185 return tags.get(tag).intValue();
189 public int getTagCount(String tagtype){
190 return getTagCount(new TagDescriptor(tagtype));
193 public FlagState[] clearTag(TagDescriptor tag){
194 if (tags.containsKey(tag)){
195 switch(tags.get(tag).intValue()){
197 HashSet newset=(HashSet)flagstate.clone();
198 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
200 return new FlagState[]{new FlagState(newset,cd,newtags)};
203 //two possibilities - count remains 2 or becomes 1
205 HashSet newset1=(HashSet)flagstate.clone();
206 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
209 HashSet newset2=(HashSet)flagstate.clone();
210 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
211 newtags1.put(tag,new Integer(ONETAG));
212 return new FlagState[] {new FlagState(newset1, cd, newtags2),
213 new FlagState(newset2, cd, newtags2)};
218 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
222 /** Creates a string description of the flagstate
223 * e.g. a flagstate with five flags could look like 01001
224 * @param flags an array of flagdescriptors.
225 * @return string representation of the flagstate.
227 public String toString(FlagDescriptor[] flags)
229 StringBuffer sb = new StringBuffer(flagstate.size());
230 for(int i=0;i < flags.length; i++)
238 return new String(sb);
242 * @return returns the classdescriptor of the flagstate.
245 public ClassDescriptor getClassDescriptor(){
249 /** Sets the status of a specific flag in a flagstate after cloning it.
250 * @param fd FlagDescriptor of the flag whose status is being set.
251 * @param status boolean value
252 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
255 public FlagState setFlag(FlagDescriptor fd, boolean status) {
256 HashSet newset=(HashSet) flagstate.clone();
257 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
260 else if (newset.contains(fd)){
264 return new FlagState(newset, cd, newtags);
267 /** Tests for equality of two flagstate objects.
270 public boolean equals(Object o) {
271 if (o instanceof FlagState) {
272 FlagState fs=(FlagState)o;
275 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
280 public int hashCode() {
281 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
284 public String getLabel() {
288 public String getTextLabel() {
290 for(Iterator it=getFlags();it.hasNext();) {
291 FlagDescriptor fd=(FlagDescriptor) it.next();
295 label+=", "+fd.toString();
297 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
298 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
299 switch (tags.get(td).intValue()){
302 label=td.toString()+"(1)";
304 label+=", "+td.toString()+"(1)";
308 label=td.toString()+"(n)";
310 label+=", "+td.toString()+"(n)";
321 public Enumeration getTags(){
325 public int getExeTime() {
327 if(this.executeTime == -1) {
330 } catch (Exception e) {
334 return this.executeTime;
337 public void setExeTime(int exeTime) {
338 this.executeTime = exeTime;
341 public int getAndmask() {
345 public void setAndmask(int andmask) {
346 this.andmask = andmask;
349 public int getCheckmask() {
353 public void setCheckmask(int checkmask) {
354 this.checkmask = checkmask;
357 public void calExeTime() throws Exception {
358 Iterator it = this.edges();
360 FEdge fe = (FEdge)it.next();
361 if(fe.getExeTime() == -1) {
362 throw new Exception("Error: Uninitiate FEdge!");
364 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
366 this.executeTime = 0;
368 while(it.hasNext()) {
369 FEdge fe = (FEdge)it.next();
370 int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
371 if(temp < this.executeTime) {
372 this.executeTime = temp;
377 public Object clone() {
380 o = (FlagState)super.clone();
381 } catch(CloneNotSupportedException e){
384 o.uid = FlagState.nodeid++;
385 o.edges = new Vector();
386 for(int i = 0; i < this.edges.size(); i++) {
387 o.edges.addElement(this.edges.elementAt(i));
389 o.inedges = new Vector();
390 for(int i = 0; i < this.inedges.size(); i++) {
391 o.inedges.addElement(this.inedges.elementAt(i));
396 public void init4Simulate() {
400 public FEdge process(TaskDescriptor td) {
403 // refresh all the expInvokeNum of each edge
404 for(int i = 0; i < this.edges.size(); i++) {
405 next = (FEdge)this.edges.elementAt(i);
406 next.setExpInvokeNum((int)Math.round(this.invokeNum * (next.getProbability() / 100)));
409 // find the one with the biggest gap between its actual invoke time and the expected invoke time
410 // and associated with task td
413 for(int i = 0; i < this.edges.size(); i++) {
414 int temp = ((FEdge)this.edges.elementAt(index)).getInvokeNumGap();
415 if((temp > gap) && (next.getTask().equals(td))){
420 next = (FEdge)this.edges.elementAt(index);