Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Monitor.java

00001 package gov.nasa.arc.ase.jpf.jvm;
00002 
00003 import gov.nasa.arc.ase.jpf.*;
00004 import gov.nasa.arc.ase.util.Debug;
00005 import gov.nasa.arc.ase.util.HashData;
00006 import java.io.*;
00007 import java.util.*;
00008 // ifdef RACE
00009 import gov.nasa.arc.ase.jpf.jvm.runtime.*;
00010 //#endif RACE
00011 
00012 public class Monitor implements Cloneable { 
00013   int   locking_thread  = -1;
00014   int   lock_count  = 0;
00015   List  waiting_threads = new ArrayList();
00016 
00017   public Monitor() {
00018   }  
00019   public Monitor(int lt, int lc, List wt) {
00020     locking_thread = lt;
00021     lock_count = lc;
00022     waiting_threads = wt;
00023   }  
00024 // ifdef RACE
00025   private void ANALYZE_lock(ThreadInfo th, Ref ref) {
00026     if (Analyze.on()) {
00027       th.getLockSet().addLock(ref);
00028       if (Analyze.debug_on()) {
00029     Analyze.println("--- LOCK ------------");
00030     Analyze.println("Thread " + th.getThreadReference() 
00031         + " locks object [" + ref + "]");      
00032     th.getLockSet().print();
00033       }
00034     }
00035   }  
00036   private void ANALYZE_unlock(ThreadInfo th, Ref ref) {
00037     if (Analyze.on()) {
00038       th.getLockSet().deleteLock(ref);      
00039       if (Analyze.debug_on()) {
00040     Analyze.println("--- UNLOCK ----------");
00041     Analyze.println("Thread " + th.getThreadReference() 
00042         + " releases object [" + ref + "]"); 
00043     th.getLockSet().print();
00044       }
00045     }    
00046   }  
00047   private void ANALYZE_wait(ThreadInfo th, Ref ref) {
00048     if (Analyze.on()) {
00049       th.getLockSet().deleteLock(ref);
00050       if (Analyze.debug_on()) {
00051     Analyze.println("--- WAIT ------------");
00052     Analyze.println("Thread " + th.getThreadReference() 
00053         + " waits on object [" + ref + "]");
00054     th.getLockSet().print();
00055       }    
00056     }
00057   }  
00058   public boolean checkLock(ThreadInfo th) {
00059     if (locking_thread == -1) 
00060       return true;
00061     return (locking_thread == th.getThreadReference());
00062   }  
00063   public boolean checkLockAfterNotified(ThreadInfo th) {
00064     return checkLock(th);
00065   }  
00066 //#endif RACE
00067 
00068   public Object clone() {
00069     try {
00070       Monitor m = (Monitor)super.clone();
00071       m.locking_thread = locking_thread;
00072       m.lock_count = lock_count;
00073       m.waiting_threads = new ArrayList();
00074       for(int i = 0; i < waiting_threads.size(); i++)
00075     m.waiting_threads.add(waiting_threads.get(i));
00076       return m; 
00077     } catch(CloneNotSupportedException e) {
00078       throw new InternalError(e.toString());
00079     }  
00080   }  
00081   public boolean equals(Object obj) {
00082     Monitor m    = (Monitor)obj;
00083 
00084     if (locking_thread != m.getLockingThread()) return false;
00085     if (lock_count != m.getLockCount()) return false;
00086 
00087     List waiting = m.waiting_threads;
00088 
00089     if (waiting_threads.size() != waiting.size()) return false;
00090 
00091     for(int i = 0; i < waiting_threads.size(); i++)
00092       if (((Integer)waiting_threads.get(i)).compareTo(waiting.get(i)) != 0) return false;
00093 
00094     return true;
00095   }  
00096   public int getLockCount() {
00097     return lock_count;
00098   }  
00099   public int getLockingThread() {
00100     return locking_thread;
00101   }  
00102   public List getWaitingThreads() {
00103     return waiting_threads;
00104   }  
00105   public void hash(HashData hd) {
00106     hd.add(lock_count);
00107 
00108     for(int i = 0, l = waiting_threads.size(); i < l; i++)
00109       hd.add(((Integer)waiting_threads.get(i)).intValue());
00110   }  
00111   public int hashCode() {
00112     HashData hd = new HashData();
00113 
00114     hd.add(lock_count);
00115 
00116     for(int i = 0, l = waiting_threads.size(); i < l; i++)
00117       hd.add(((Integer)waiting_threads.get(i)).intValue());
00118 
00119     return hd.getValue();
00120   }  
00121   public boolean lock(ThreadInfo th, Ref ref) {
00122     if (locking_thread == -1) { 
00123       locking_thread = th.getThreadReference();
00124 // ifdef RACE
00125       ANALYZE_lock(th,ref);
00126       LOCKORDER_lock(th,ref);
00127 //#endif RACE
00128     }
00129     if (locking_thread == th.getThreadReference()) {
00130       lock_count++;  
00131 // ifdef DEBUG
00132 
00133 //#endif DEBUG
00134       return true;
00135     } else {
00136 // ifdef DEBUG
00137 
00138 
00139 //#endif DEBUG
00140       return false;
00141     }
00142   }  
00143   public boolean lockAfterNotified(ThreadInfo th, Ref ref) {
00144     if (lock(th,ref)) {
00145       th.setStatus(STATUS.RUNNING);
00146       lock_count = th.getLockCount();
00147       return true;
00148     }
00149     else
00150       return false;
00151   }  
00152   private void LOCKORDER_lock(ThreadInfo th, Ref ref) {
00153     if (LockOrder.on()) {
00154       VirtualMachine vm = (VirtualMachine)Engine.vm;
00155       KernelState ks = (KernelState)vm.getKernelState();
00156       String className;
00157       if(ref.isClass)
00158     className = ks.static_area.getClass(ref.reference).getClassName();
00159       else
00160     className = ks.dynamic_area.getClass(ref.reference).getClassName();
00161       th.getLockTree().lock(LockPool.get(new Lock(ref,className)));
00162     }
00163   }  
00164   private void LOCKORDER_unlock(ThreadInfo th) {
00165     if (LockOrder.on()) {
00166       th.getLockTree().unlock();
00167     }
00168   }  
00169   private void LOCKORDER_wait(ThreadInfo th) {
00170     if (LockOrder.on()) {
00171       th.getLockTree().unlock();
00172     }
00173   }  
00174   public void notify(KernelState ks, Scheduler sch) {
00175     int notify_index = sch.getCurrentNotify();
00176 
00177     if (notify_index < waiting_threads.size()) {
00178       if ((notify_index + 1) < waiting_threads.size()) {
00179 // ifdef DEBUG
00180 
00181 
00182 //#endif DEBUG
00183     TransitionResult.setNotified();
00184       }
00185       else {
00186 // ifdef DEBUG
00187 
00188 //#endif DEBUG
00189     TransitionResult.clearNotified();
00190       }
00191       int thread_index = 
00192     ((Integer)waiting_threads.remove(notify_index)).intValue();
00193       ThreadInfo th = (ThreadInfo)ks.getThreadInfo(thread_index);
00194       th.setStatus(STATUS.NOTIFIED);
00195     }
00196   }  
00197   public void notifyAll(KernelState ks) {
00198     while (!waiting_threads.isEmpty()) {
00199       int thread_index = ((Integer)waiting_threads.remove(0)).intValue();
00200       ThreadInfo th = (ThreadInfo)ks.getThreadInfo(thread_index);
00201       th.setStatus(STATUS.NOTIFIED);
00202     }
00203   }  
00204   public void unlock(ThreadInfo th, Ref ref) {
00205 // ifdef DEBUG
00206 
00207 //#endif DEBUG
00208     lock_count--;
00209     if (lock_count < 0) {
00210       Debug.println(Debug.WARNING,"Illegal Monitor Operation");
00211     }
00212     if (lock_count == 0) {
00213       locking_thread = -1;
00214 // ifdef RACE
00215       ANALYZE_unlock(th,ref);
00216       LOCKORDER_unlock(th);
00217 //#endif RACE
00218     }
00219   }  
00220   public void wait(ThreadInfo th, Ref ref) {
00221     th.setStatus(STATUS.WAITING);
00222     th.setLockCount(lock_count); // be aware: perhaps lock_count - 1.
00223     waiting_threads.add(new Integer(th.getThreadReference()));
00224     locking_thread = -1;
00225     lock_count = 0;
00226 // ifdef RACE
00227     ANALYZE_wait(th,ref);
00228     LOCKORDER_wait(th);
00229 //#endif RACE
00230   }  
00231 }

Generated at Thu Feb 7 06:50:31 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001