Source code for /engineering/autohit-1998/autohit/vm/VMAutomat.javaOriginal file VMAutomat.java
   1 /**
   2  * .
   3  * Copyright � 1999 Erich P G.
   4  *
   5  */
   6  
   7 package autohit.vm;
   8 
   9 import autohit.utils.LockedQueue;
  10 
  11 /**
  12  * A VM automat.  This is a different kind of VM context.  Basically, it accepts a
  13  * queue through which it can be controlled.  Send it a Sim to run or an Integer(VM.STATE_*) to 
  14  * effect the state.  NOTE that these are "requests."  There is no guarentee that the order will
  15  * be followed.
  16  * <p>
  17  * Here is a state diagram which shows some off the effects of control "requests."  kill() is
  18  * a special case, where another thread calls the Automat's kill() method.
  19  * <p>
  20  * <pre>
  21  *                  | RUNNING      | PAUSED       | NO_VM 
  22  *  A VM            | ignored      | ignored      | vm is run
  23  *  STATE_NEW       | ignored      | ignored      | ignored
  24  *  STATE_RUNNING   | ignored      | vm paused    | ignored
  25  *  STATE_PAUSED    | vm resumed   | ignored      | ignored
  26  *  STATE_DONE      | vm discarded | vm discarded | ignored
  27  *  STATE_NO_VM     | ignored      | ignored      | ignored
  28  *  die()          | <---  VM Killed and Automat dies ------>  
  29  * </pre>
  30  *
  31  * <p>
  32  * @author Erich P. Gatejen
  33  * @version 1.0
  34  * <i>Version History</i>
  35  * <code>EPG - Initial - 12Feb99</code> 
  36  * 
  37  */
  38 public class VMAutomat extends Thread {
  39 	
  40 	// --- FINAL FIELDS ------------------------------------------------------	
  41      
  42 	// --- FIELDS ------------------------------------------------------------
  43 
  44     /**
  45      *  A runnable VM.  This will be a fully implemented derived-class
  46      *  of VM.
  47      */      	    
  48      private VM             rVM;
  49      
  50 
  51     /**
  52      *  The control queue.  This thread will watch the queue for things to do.
  53      */      	    
  54      private LockedQueue    cQ;
  55 
  56 
  57     /**
  58      *  Flags a kill order.
  59      */      	    
  60      private boolean        killed;
  61           
  62     
  63 	// --- PUBLIC METHODS ----------------------------------------------------	
  64 
  65     /**
  66      *  Constructor.
  67      */      
  68      public VMAutomat(LockedQueue   controlQueue) {
  69 
  70           // Make this when we run.  otherwise, we wont own it,
  71           cQ     = controlQueue;
  72           rVM    = null;
  73           killed = false;
  74           
  75           this.setDaemon(true);             
  76      }
  77 
  78 
  79     /**
  80      *  Return the last known stable status.  This is not 100% accurate, as the
  81      *  automate MAY be in the process of shifting status while this is being queried.
  82      *  It should be close enough for most purposes; the window of possible inaccuracy is 
  83      *  perdy small...
  84      *
  85      *  This method can be called by any thread.
  86      *
  87      *  @return a VM.STATUS_* int value.
  88      *
  89      *  @see autohit.vm.VM    
  90      */  
  91      public synchronized int getLastKnownStatus() {
  92         
  93         if (rVM == null) return VM.STATE_NO_VM;
  94         else return rVM.getState();
  95      }
  96 
  97 
  98     /**
  99      *  Kills the Automat as soon as possible.
 100      */      
 101      public synchronized void kill(LockedQueue   controlQueue) {
 102 
 103           // Make this when we run.  otherwise, we wont own it,
 104           cQ  = controlQueue;
 105           rVM = null; 
 106           
 107           this.setDaemon(true);             
 108      }
 109 
 110     /**
 111      *  Run the automat
 112      */  
 113      public void run() {
 114 
 115           Object    dqo;    // temporary dequeued object reference.
 116           Integer   tio;    // temporary integer object
 117           
 118           // Enter a loop until some other thread Kill()s me....
 119            while (killed == false) {
 120             
 121                 // Nothing is running.  Wait on the queue for a VM
 122                 if (!cQ.hasObject()) cQ.block(true);
 123                 dqo = cQ.get();
 124                
 125                 // Only interested in VMs
 126                 if (!(dqo instanceof VM)) continue;               
 127 
 128                 // Any VM exception will make the context
 129                 // dump the VM.  This will also catch the NullPointerException
 130                 // that would be caused by a spurious context thread unblock when
 131                 // a VM has not be set for execution.
 132                 try {
 133                    
 134                     // Start the VM
 135                     rVM = (VM)dqo;
 136                     rVM.start();
 137                     
 138                     // Specific VM loop
 139                     do {
 140                                  
 141                         // Check the queue for control objects...  Control objects take precedence
 142                         // over instruciton execution.
 143                         if (cQ.hasObject()) {
 144                          
 145                             dqo = cQ.get();
 146                          
 147                             // Only care about Integers
 148                             if (dqo instanceof Integer) {
 149                             
 150                                 tio = (Integer)dqo;
 151                                 switch(tio.intValue()) {
 152                                     
 153                                     case VM.STATE_RUNNING:
 154                                     
 155                                         // No need to check state.
 156                                         rVM.resume();
 157                                         break;                                            
 158                                     
 159                                     case VM.STATE_PAUSED:
 160                                      
 161                                         // No need to check state.
 162                                         // Since we have paused, this thread doesnt need
 163                                         // to do anything until another control arrives.
 164                                         // Go ahead and block on the queue.
 165                                         rVM.pause();
 166                                         cQ.block(true);
 167                                        break;                                     
 168                                     
 169                                     case VM.STATE_DONE:
 170                                         
 171                                         // DONE with this VM.  Kill the reference.
 172                                         rVM = null;
 173                                     
 174                                     default:
 175                                         // ignore all others
 176                                         break;                                    
 177                                     
 178                                 } // end switch
 179                                 
 180                             } // end if Integer
 181                             
 182                         } else {
 183 
 184                             // Go ahead and execute an instruction
 185                             rVM.execute();
 186                         }                       
 187                            
 188                     } while (rVM != null);
 189                
 190                } catch (Exception e) {
 191                     // Don't actuall have to do anything...
 192                } 
 193                               
 194                // The VM will die now... just in case.
 195                rVM = null;                            
 196           
 197           }
 198           
 199           // Last out the door turn off the lights...
 200           // DO NOT put ANY other code beyond the following statements
 201           // or you are liable to deadlock other Threads.
 202           yield();
 203      }
 204      
 205 	// --- PRIVATE METHODS ---------------------------------------------------	     
 206 
 207 }