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
00009 public class LockStatus extends LockSet{
00010
00011 private static final int VIRGIN = 0;
00012 private static final int EXCLUSIVE = 1;
00013 private static final int SHARED = 2;
00014 private static final int SHARED_MODIFIED = 3;
00015 private static final int FAILED = 4;
00016
00017 private int state = VIRGIN;
00018 private AccessList accesses = new AccessList();
00019
00020 private ThreadInfo first_thread;
00021
00022
00023 public void checkRead(ThreadInfo thread,String className,String fieldName){
00024 if (!isSafe(thread,false)){
00025 Runner.race_conditions++;
00026 printExplanation(className,fieldName);
00027 RaceWindow.addRace(this);
00028 }
00029 }
00030 public void checkReadArray(ThreadInfo thread,int index){
00031 if (!isSafe(thread,false)){
00032 Runner.race_conditions++;
00033 printArrayExplanation(index);
00034 RaceWindow.addRace(this);
00035 }
00036 }
00037 public void checkWrite(ThreadInfo thread,String className,String fieldName){
00038 if (!isSafe(thread,true)){
00039 Runner.race_conditions++;
00040 printExplanation(className,fieldName);
00041 RaceWindow.addRace(this);
00042 }
00043 }
00044 public void checkWriteArray(ThreadInfo thread,int index){
00045 if (!isSafe(thread,true)){
00046 Runner.race_conditions++;
00047 printArrayExplanation(index);
00048 RaceWindow.addRace(this);
00049 }
00050 }
00051 public AccessList getAccessList(){
00052 return accesses;
00053 }
00054 private boolean isSafe(ThreadInfo thread,boolean isWrite){
00055 switch (state){
00056 case VIRGIN :
00057 accesses.addInit(thread);
00058 first_thread = thread;
00059 state = EXCLUSIVE;
00060 return true;
00061 case EXCLUSIVE :
00062 if (thread == first_thread)
00063 return true;
00064 else{
00065 if (isWrite){
00066 accesses.addWrite(thread);
00067 refineFirst(thread);
00068 if (isEmpty()){
00069 state = FAILED;
00070 return false;
00071 }
00072 else{
00073 state = SHARED_MODIFIED;
00074 return true;
00075 }
00076 }
00077 else{
00078 accesses.addRead(thread);
00079 refineFirst(thread);
00080 state = SHARED;
00081 return true;
00082 }
00083 }
00084 case SHARED :
00085 if (isWrite){
00086 accesses.addWrite(thread);
00087 refine(thread);
00088 if (isEmpty()){
00089 state = FAILED;
00090 return false;
00091 }
00092 else{
00093 state = SHARED_MODIFIED;
00094 return true;
00095 }
00096 }
00097 else{
00098 if (refine(thread))
00099 accesses.addRead(thread);
00100 return true;
00101 };
00102 case SHARED_MODIFIED :
00103 if (refine(thread)){
00104 if (isWrite)
00105 accesses.addWrite(thread);
00106 else
00107 accesses.addRead(thread);
00108 };
00109 if (isEmpty()){
00110 state = FAILED;
00111 return false;
00112 }
00113 else{
00114 return true;
00115 }
00116 case FAILED :
00117 return true;
00118 default :
00119 Debug.println(Debug.ERROR, "*** LockStatus state undefined : " + state);
00120 System.exit(0);
00121 return false;
00122 };
00123 }
00124 public void print(){
00125 Analyze.print("Variable state = ");
00126 switch(state){
00127 case VIRGIN : Analyze.println("VIRGIN");break;
00128 case EXCLUSIVE : Analyze.println("EXCLUSIVE");break;
00129 case SHARED : Analyze.println("SHARED");break;
00130 case SHARED_MODIFIED : Analyze.println("SHARED_MODIFIED");break;
00131 case FAILED : Analyze.println("FAILED");break;
00132 };
00133 Analyze.print("Lock set = ");
00134 printSet();
00135 }
00136 private void printArrayExplanation(int index){
00137 String descr = "Array (in index " + index + ")";
00138 printExplanationPlus(descr);
00139 }
00140 private void printExplanation(String className, String fieldName){
00141 String descr = "Variable " + fieldName + " in class " + className;
00142 printExplanationPlus(descr);
00143 }
00144 private void printExplanationPlus(String descr){
00145 Analyze.println("\n\n");
00146 Analyze.println("******************************");
00147 Analyze.println("Race condition!");
00148 Analyze.println("------------------------------");
00149 Analyze.println(descr);
00150 Analyze.println("is accessed unprotected.");
00151 Analyze.println("******************************");
00152 Analyze.println("");
00153 Analyze.println("=============================");
00154 Analyze.println(" *** Access description: *** ");
00155 Analyze.println("=============================");
00156 accesses.print();
00157 Analyze.println("=============================");
00158 }
00159 private boolean refine(ThreadInfo thread){
00160 int cardinality_before = cardinality();
00161 intersect(thread.getLockSet());
00162 return (cardinality() < cardinality_before);
00163 }
00164 private void refineFirst(ThreadInfo thread){
00165 union(thread.getLockSet());
00166 }
00167 }