00001 package gov.nasa.arc.ase.jpf.jvm.runtime;
00002
00003 import gov.nasa.arc.ase.jpf.*;
00004 import gov.nasa.arc.ase.jpf.jvm.*;
00005 import java.util.*;
00006 import gov.nasa.arc.ase.util.Debug;
00007
00008 public class Depend {
00009
00010 private static HashMap map = new HashMap();
00011
00012
00013 public static void addFork(ThreadInfo father,ThreadInfo son) {
00014 Unit fatherUnit = mkThreadUnit(father);
00015 Unit sonUnit = mkThreadUnit(son);
00016 DependInfo info = new DependInfo(fatherUnit);
00017 map.put(sonUnit,info);
00018 }
00019 public static void addMain(ThreadInfo th) {
00020 Unit threadUnit = mkThreadUnit(th);
00021 map.put(threadUnit,new DependInfo());
00022 }
00023 public static void addRead(ThreadInfo th,Ref ref) {
00024 Unit threadUnit = mkThreadUnit(th);
00025 Unit objectUnit = mkObjectUnit(ref);
00026 getInfo(threadUnit).addRead(objectUnit);
00027 }
00028 public static void addWrite(ThreadInfo th,Ref ref) {
00029 Unit threadUnit = mkThreadUnit(th);
00030 Unit objectUnit = mkObjectUnit(ref);
00031 getInfo(threadUnit).addWrite(objectUnit);
00032 }
00033 public static eHashSet createWindow(eHashSet threads) {
00034 eHashSet threadNames = new eHashSet();
00035 if (on()) {
00036 eHashSet window = new eHashSet();
00037 Iterator threads_it = threads.iterator();
00038 ThreadInfo thread;
00039 while(threads_it.hasNext()) {
00040 thread = (ThreadInfo)threads_it.next();
00041 window.add(mkThreadUnit(thread));
00042 };
00043 eHashSet eWindow = extendWindow(window);
00044 Iterator eWindow_it = eWindow.iterator();
00045 Unit threadUnit;
00046 while(eWindow_it.hasNext()) {
00047 threadUnit = (Unit)eWindow_it.next();
00048 threadNames.add(threadUnit.getClassName());
00049 };
00050 }
00051 else {
00052 Iterator threads_it = threads.iterator();
00053 ThreadInfo thread;
00054 while(threads_it.hasNext()) {
00055 thread = (ThreadInfo)threads_it.next();
00056 threadNames.add(thread.getClassInfo().getClassName());
00057 };
00058 };
00059 return threadNames;
00060 }
00061 public static boolean debug_on() {
00062 return Debug.getDebugLevel(Debug.DEPEND) > 0;
00063 }
00064 private static eHashSet extendWindow(eHashSet window) {
00065 eHashSet passedThreads = new eHashSet();
00066 eHashSet waitingThreads = (eHashSet)window.clone();
00067 Unit thread;
00068 DependInfo info;
00069 Unit ancestor;
00070 while(!waitingThreads.isEmpty()) {
00071 thread = (Unit)waitingThreads.choose();
00072 if (!passedThreads.contains(thread)) {
00073 passedThreads.add(thread);
00074 info = getInfo(thread);
00075 ancestor = info.getThread();
00076 if (ancestor != null) waitingThreads.add(ancestor);
00077 waitingThreads.union(writingThreads(info.getReads()));
00078 };
00079 };
00080 return passedThreads;
00081 }
00082 public static DependInfo getInfo(Unit thread) {
00083 return (DependInfo)map.get(thread);
00084 }
00085 private static Unit mkObjectUnit(Ref ref) {
00086 VirtualMachine vm = (VirtualMachine)Engine.vm;
00087 KernelState ks = (KernelState)vm.getKernelState();
00088 String className;
00089
00090 if(ref.isClass()) {
00091 StaticArea sa = ks.static_area;
00092 className = sa.getClass(ref.getReference()).getClassName();
00093 } else {
00094 DynamicArea da = ks.dynamic_area;
00095 className = da.getClass(ref.getReference()).getClassName();
00096 }
00097
00098 return UnitPool.get(new Unit(ref,className));
00099 }
00100 private static Unit mkThreadUnit(ThreadInfo th) {
00101 Ref ref = th.getReference();
00102 String className = th.getClassInfo().getClassName();
00103 return UnitPool.get(new Unit(ref, className));
00104 }
00105 public static boolean on() {
00106 return VirtualMachine.options.depend;
00107 }
00108 public static void print() {
00109 Unit thread;
00110 DependInfo info;
00111 Set keys = map.keySet();
00112 Iterator keys_it = keys.iterator();
00113 Debug.println(Debug.ERROR, "");
00114 Debug.println(Debug.ERROR, "#################");
00115 Debug.println(Debug.ERROR, "# Dependencies: #");
00116 Debug.println(Debug.ERROR, "#################");
00117 while (keys_it.hasNext()) {
00118 thread = (Unit)keys_it.next();
00119 info = getInfo(thread);
00120 Debug.println(Debug.ERROR, "");
00121 Debug.println(Debug.ERROR, "================");
00122 thread.print();
00123 Debug.println(Debug.ERROR, ":");
00124 Debug.println(Debug.ERROR, "================");
00125 info.print();
00126 }
00127 }
00128 private static eHashSet writingThreads(eHashSet objs) {
00129 Iterator keys_it = map.keySet().iterator();
00130 eHashSet writing = new eHashSet();
00131 Unit thread;
00132 while (keys_it.hasNext()) {
00133 thread = (Unit)keys_it.next();
00134 if (objs.overlaps(getInfo(thread).getWrites()))
00135 writing.add(thread);
00136 };
00137 return writing;
00138 }
00139 }