00001 package gov.nasa.arc.ase.jpf.jvm; 00002 00003 import gov.nasa.arc.ase.jpf.iSystemState; 00004 import gov.nasa.arc.ase.jpf.iThreadInfo; 00005 import gov.nasa.arc.ase.jpf.JPFErrorException; 00006 import java.io.BufferedReader; 00007 import java.io.InputStreamReader; 00008 import java.io.IOException; 00009 import java.util.BitSet; 00010 00011 public class InteractiveScheduler extends Scheduler { 00012 private static BufferedReader br = new BufferedReader( 00013 new InputStreamReader(System.in)); 00014 private static boolean quit = false; 00015 private int thread; 00016 private int random; 00017 private boolean lastRandom; 00018 00019 public InteractiveScheduler(iSystemState ss) { 00020 initialize(ss); 00021 } 00022 public InteractiveScheduler(InteractiveScheduler is) { 00023 quit = is.quit; 00024 thread = is.thread; 00025 random = is.random; 00026 lastRandom = is.lastRandom; 00027 ss = null; 00028 } 00029 public Object clone() { 00030 return new InteractiveScheduler(this); 00031 } 00032 public int getRandom() { 00033 return random; 00034 } 00035 public int getThread() { 00036 return thread; 00037 } 00038 public void initialize(iSystemState ss) { 00039 this.ss = (SystemState)ss; 00040 thread = 0; 00041 random = 0; 00042 lastRandom = true; 00043 } 00044 public iThreadInfo locateThread(iSystemState ss) { 00045 if(quit) return null; 00046 00047 int nthreads = ss.getThreadCount(); 00048 int nrunnable = 0; 00049 BitSet runnable = new BitSet(); 00050 00051 for(int i = 0; i < nthreads; i++) { 00052 iThreadInfo th = ss.getThreadInfo(i); 00053 if(th.isRunnable()) { 00054 runnable.set(i); 00055 nrunnable++; 00056 } 00057 } 00058 00059 if(nrunnable == 0) { 00060 System.out.println("Deadlock: backing up"); 00061 return null; 00062 } 00063 00064 System.out.print("Runnable threads [" + nrunnable + "]: "); 00065 for(int i = 0; i < nthreads; i++) { 00066 if(runnable.get(i)) { 00067 if(i == thread) { 00068 System.out.print("[" + i + "] "); 00069 } else { 00070 System.out.print(i + " "); 00071 } 00072 } 00073 } 00074 System.out.println(); 00075 00076 while(true) { 00077 try { 00078 System.out.print("> "); 00079 String s = br.readLine(); 00080 if(s.equals("quit") || s.equals("q")) { 00081 quit = true; 00082 return null; 00083 } else if(s.equals("backtrack") || s.equals("back") || s.equals("b")) { 00084 return null; 00085 } else if(s.equals("show") || s.equals("s")) { 00086 while(true) { 00087 System.out.print("show> "); 00088 s = br.readLine(); 00089 if(s.equals("")) break; 00090 try { 00091 int l = Integer.parseInt(s); 00092 if(runnable.get(l)) { 00093 ThreadInfo th = (ThreadInfo)ss.getThreadInfo(l); 00094 System.out.println(th.getMethod().getCompleteName() + ":" + th.getPC().getPosition() + " " + th.getPC()); 00095 break; 00096 } 00097 } catch(NumberFormatException e) { 00098 } 00099 } 00100 } else if(s.equals("random") || s.equals("r")) { 00101 while(true) { 00102 System.out.println("Current random: " + random); 00103 System.out.print("random> "); 00104 s = br.readLine(); 00105 if(s.equals("")) break; 00106 try { 00107 random = Integer.parseInt(s); 00108 break; 00109 } catch(NumberFormatException e) { 00110 } 00111 } 00112 } else if(s.equals("help") || s.equals("h") || s.equals("?")) { 00113 System.out.println("command:"); 00114 System.out.println(" quit"); 00115 System.out.println(" random"); 00116 System.out.println(" backtrack"); 00117 System.out.println(" help"); 00118 } else { 00119 if(runnable.get(thread) && s.equals("")) 00120 break; 00121 try { 00122 int i = Integer.parseInt(s); 00123 if(runnable.get(i)) { 00124 thread = i; 00125 break; 00126 } 00127 } catch(NumberFormatException e) { 00128 } 00129 } 00130 } catch(IOException e) { 00131 throw new JPFErrorException(e.getMessage()); 00132 } 00133 } 00134 00135 System.out.println("Running thread " + thread); 00136 00137 return ss.getThreadInfo(thread); 00138 } 00139 public void next() { 00140 if(lastRandom) { 00141 random = 0; 00142 thread++; 00143 } else { 00144 random++; 00145 } 00146 } 00147 public int random(int max) { 00148 lastRandom = (random == max-1); 00149 00150 return random; 00151 } 00152 }