00001 package gov.nasa.arc.ase.jpf.jvm;
00002
00003 import gov.nasa.arc.ase.jpf.Engine;
00004 import gov.nasa.arc.ase.jpf.iSystemState;
00005 import gov.nasa.arc.ase.jpf.iThreadInfo;
00006 import gov.nasa.arc.ase.jpf.JPFErrorException;
00007 import gov.nasa.arc.ase.util.Debug;
00008 import java.util.BitSet;
00009 import java.util.Random;
00010
00011 public class RandomOrderScheduler extends Scheduler implements Cloneable {
00012 private static Random rand =
00013 new Random(Engine.options.use_time_for_seed ? System.currentTimeMillis() :
00014 Engine.options.random_seed);
00015 public iSystemState ss;
00016 private int thread;
00017 private int random;
00018 private BitSet runThread;
00019 private BitSet[] runRandom;
00020 private int[] randomSize;
00021
00022 public RandomOrderScheduler(iSystemState ss) {
00023 Debug.println(Debug.MESSAGE, "Random Order Scheduler");
00024 initialize(ss);
00025 }
00026 public void backtrackTo(ArrayOffset storing, Object backtrack) {
00027 copy((RandomOrderScheduler)backtrack);
00028 }
00029 public Object clone() {
00030 RandomOrderScheduler s = new RandomOrderScheduler (null);
00031
00032 s.thread = thread;
00033 s.random = random;
00034
00035 s.ss = null;
00036 if (runThread != null)
00037 s.runThread = (BitSet)runThread.clone();
00038 if (runRandom != null) {
00039 s.runRandom = new BitSet[runRandom.length];
00040 for (int i = 0; i < runRandom.length; i++)
00041 if (runRandom[i] != null)
00042 s.runRandom[i] = (BitSet)runRandom[i].clone();
00043 }
00044 if (randomSize != null)
00045 s.randomSize = (int[])randomSize.clone();
00046 return s;
00047 }
00048 public void copy(RandomOrderScheduler sch) {
00049 if (sch.runThread != null)
00050 runThread = (BitSet)sch.runThread.clone();
00051 if (sch.runRandom != null) {
00052 runRandom = new BitSet[sch.runRandom.length];
00053 for (int i = 0; i < sch.runRandom.length; i++)
00054 runRandom[i] = (BitSet)sch.runRandom[i].clone();
00055 }
00056 if (sch.randomSize != null)
00057 randomSize = (int[])sch.randomSize.clone();
00058 thread = sch.thread;
00059 random = sch.random;
00060 }
00061 public Object getBacktrackData() {
00062 return clone();
00063 }
00064 public int getRandom() {
00065 return random;
00066 }
00067 public int[] getStoringData() {
00068 return new int[0];
00069 }
00070 public int getThread() {
00071 return thread;
00072 }
00073 public void initialize(iSystemState ss) {
00074 this.ss = ss;
00075 thread = 0;
00076 random = 0;
00077 runThread = new BitSet();
00078 runRandom = null;
00079 randomSize = null;
00080 }
00081 private boolean isComplete(int th) {
00082 if (randomSize[th] == 0)
00083 return true;
00084 boolean finished = true;
00085 for (int i = 0; i < randomSize[th]; i++) {
00086 finished = finished && runRandom[th].get(i);
00087 }
00088 return finished;
00089 }
00090 public iThreadInfo locateThread(iSystemState ss) {
00091 thread = pickNextThread(ss);
00092 if (thread == -1) {
00093
00094 return null;
00095 }
00096
00097 return ss.getThreadInfo(thread);
00098 }
00099 public void next() {
00100 if (isComplete(thread))
00101 runThread.set(thread);
00102 }
00103 private int pickNextRandom(int th, int n) {
00104 randomSize[th] = n;
00105
00106 int nchoices = 0;
00107 int [] choices = new int[n];
00108 for (int i = 0; i < n; i++)
00109 if (!runRandom[th].get(i))
00110 choices[nchoices++] = i;
00111
00112 int r = rand.nextInt(nchoices);
00113 runRandom[th].set(choices[r]);
00114
00115 return choices[r];
00116 }
00117 private int pickNextThread(iSystemState ss) {
00118 int nthreads = 0;
00119 int n = ss.getThreadCount ();
00120 int[] refs = new int[n];
00121
00122 if (runRandom == null) {
00123 runRandom = new BitSet[n];
00124 for (int i = 0; i < n; i++)
00125 runRandom[i] = new BitSet ();
00126 }
00127
00128 if (randomSize == null)
00129 randomSize = new int[n];
00130
00131 for(int i = 0; i < n; i++) {
00132 iThreadInfo th = ss.getThreadInfo(i);
00133 if (!(runThread.get(i)) && (th.isRunnable())) {
00134 refs[nthreads++] = i;
00135 }
00136 }
00137
00138 if(nthreads == 0)
00139 return -1;
00140
00141 int r = rand.nextInt(nthreads);
00142
00143 return refs[r];
00144 }
00145 public int random(int max) {
00146 random = pickNextRandom(thread, max);
00147 return random;
00148 }
00149 }