00001 package gov.nasa.arc.ase.jpf.jvm.runtime;
00002
00003 import javax.swing.tree.*;
00004 import java.util.*;
00005 import gov.nasa.arc.ase.jpf.*;
00006 import gov.nasa.arc.ase.jpf.jvm.*;
00007 import gov.nasa.arc.ase.util.Debug;
00008
00009 public class LockOrder{
00010
00011 public static void analyze(LockNode masterNode,LockTree slaveTree){
00012 analyzeThis(masterNode,slaveTree);
00013 Enumeration children = masterNode.children();
00014 LockNode child;
00015 while (children.hasMoreElements()){
00016 child = (LockNode)children.nextElement();
00017 analyze(child,slaveTree);
00018 };
00019 slaveTree.unMark(masterNode.getLockNodeInfo().getLock());
00020 }
00021 public static void analyze(LockTree masterTree, LockTree slaveTree){
00022 LockNode root = masterTree.getRoot();
00023 Enumeration topNodes = root.children();
00024 LockNode topNode;
00025 while (topNodes.hasMoreElements()){
00026 topNode = (LockNode)topNodes.nextElement();
00027 analyze(topNode,slaveTree);
00028 }
00029 }
00030 public static void analyze(VirtualMachine vm){
00031 KernelState ks = (KernelState)vm.getKernelState();
00032 printStart(ks);
00033 int nthreads = ks.getThreadCount();
00034 for (int master = 0;master < nthreads - 1;master++){
00035 for (int slave = master+1;slave < nthreads;slave++){
00036 analyze(ks.getThreadLockTree(master), ks.getThreadLockTree(slave));
00037 }
00038 }
00039 printStatus();
00040 }
00041 public static void analyzeThis(LockNode masterNode,LockTree slaveTree){
00042 Lock lock = masterNode.getLockNodeInfo().getLock();
00043 Iterator slaveNodes = slaveTree.getLockMap().getIterator(lock);
00044 LockNode slaveNode;
00045 while (slaveNodes.hasNext()){
00046 slaveNode = (LockNode)slaveNodes.next();
00047 if (!slaveNode.isBelowMark()){
00048 HashSet pathSet = slaveNode.setAbove();
00049 analyzeThis(masterNode,pathSet,slaveNode);
00050 slaveNode.getLockNodeInfo().mark();
00051 }
00052 }
00053 }
00054 public static void analyzeThis(LockNode masterNode,HashSet setAbove,LockNode slaveNode){
00055 Lock thisLock = masterNode.getLockNodeInfo().getLock();
00056 if (setAbove.contains(thisLock)){
00057 Runner.lock_conflicts++;
00058 printConflict(masterNode,slaveNode);
00059 RaceWindow.addRace(masterNode,slaveNode);
00060 } else{
00061 Enumeration children = masterNode.children();
00062 LockNode child;
00063 while (children.hasMoreElements()){
00064 child = (LockNode)children.nextElement();
00065 analyzeThis(child,setAbove,slaveNode);
00066 };
00067 }
00068 }
00069 public static void debug_info(String msg){
00070
00071
00072
00073 }
00074 public static boolean debug_on(){
00075 return Debug.getDebugLevel(Debug.LOCK_ORDER) > 0;
00076 }
00077
00078 public static boolean on(){
00079 return VirtualMachine.options.lock_order;
00080 }
00081 public static void print(String msg){
00082 Debug.print(Debug.WARNING,msg);
00083 }
00084 private static void printConflict(LockNode masterNode,LockNode slaveNode){
00085 println("");
00086 println("");
00087 println("******************************");
00088 println("Lock order conflict!");
00089 println("------------------------------");
00090 print("Locks on ");
00091 masterNode.getLockNodeInfo().getLock().print();
00092 print(" and ");
00093 slaveNode.getLockNodeInfo().getLock().print();
00094 println("");
00095 println("are taken in opposite order.");
00096 println("******************************");
00097 println("");
00098 println("=============================");
00099 println(" *** Access description: *** ");
00100 println("=============================");
00101 println("");
00102 masterNode.print();
00103 slaveNode.print();
00104 println("==============================");
00105 }
00106 public static void println(String msg){
00107 Debug.println(Debug.WARNING,msg);
00108 }
00109 private static void printStart(KernelState ks){
00110 println("");
00111 println("LOCK ORDER ANALYSIS STARTS!");
00112 println("");
00113 if (debug_on()) printTrees(ks);
00114 }
00115 private static void printStatus(){
00116 println("");
00117 if (Runner.lock_conflicts == 0)
00118 println("No lock order conflicts!");
00119 else
00120 println("*** Total number of lock order conflicts : " + Runner.lock_conflicts);
00121 }
00122 private static void printTrees(KernelState ks){
00123 println("======================");
00124 println("Listing of Lock Trees:");
00125 println("======================");
00126 int nthreads = ks.getThreadCount();
00127 for (int threadnr = 0;threadnr < nthreads;threadnr++) {
00128 ks.getThreadLockTree(threadnr).print();
00129 }
00130 }
00131 }