00001 package edu.ksu.cis.bandera.bir;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import ca.mcgill.sable.util.*;
00036
00037 import java.util.*;
00038
00039
00040
00041
00042
00043
00044
00045 public class LockLit implements Literal, BirConstants, Cloneable {
00046
00047 int heldCount = 0;
00048 BirThread owner = null;
00049 boolean [] waiting;
00050 int [] waitHeldCount;
00051 TransSystem system;
00052 int numThreads;
00053
00054 public LockLit(TransSystem system) {
00055 this.system = system;
00056 numThreads = system.getThreads().size();
00057 waiting = new boolean[numThreads];
00058 waitHeldCount = new int[numThreads];
00059 }
00060 public void apply(Switch sw)
00061 {
00062 ((ExprSwitch) sw).caseLockLit(this);
00063 }
00064 public BirThread getOwner() { return owner; }
00065 public TransSystem getSystem() { return system; }
00066 public Type getType() { return Type.WR_lockType; }
00067 public ThreadVector getWaitingThreads() {
00068 ThreadVector waitThreads = new ThreadVector();
00069 ThreadVector threads = system.getThreads();
00070 for (int i = 0; i < threads.size(); i++) {
00071 BirThread thread = threads.elementAt(i);
00072 if (waiting[thread.getId()])
00073 waitThreads.addElement(thread);
00074 }
00075 return waitThreads;
00076 }
00077 public LockLit nextState(int operation, BirThread thread, int choice) {
00078 LockLit nextState;
00079 try {
00080 nextState = (LockLit) this.clone();
00081 } catch (CloneNotSupportedException e) { return null; }
00082 switch (operation) {
00083 case LOCK:
00084 if (owner == null)
00085 nextState.owner = thread;
00086 else
00087 nextState.heldCount++;
00088 break;
00089 case UNLOCK:
00090 if (heldCount == 0)
00091 nextState.owner = null;
00092 else
00093 nextState.heldCount--;
00094 break;
00095 case WAIT:
00096 nextState.waiting = (boolean []) waiting.clone();
00097 nextState.waiting[thread.getId()] = true;
00098 nextState.waitHeldCount = (int []) waitHeldCount.clone();
00099 nextState.waitHeldCount[thread.getId()] = heldCount;
00100 nextState.owner = null;
00101 break;
00102 case UNWAIT:
00103 nextState.heldCount = waitHeldCount[thread.getId()];
00104 nextState.owner = thread;
00105 break;
00106 case NOTIFY:
00107 nextState.waiting = (boolean []) waiting.clone();
00108 if (choice < numThreads)
00109 nextState.waiting[choice] = false;
00110 break;
00111 case NOTIFYALL:
00112 nextState.waiting = (boolean []) waiting.clone();
00113 for (int i = 0; i < numThreads; i++)
00114 nextState.waiting[i] = false;
00115 break;
00116 default:
00117 throw new RuntimeException("Bad operation code");
00118 }
00119 return nextState;
00120 }
00121 public boolean queryState(int operation, BirThread thread) {
00122 switch (operation) {
00123 case LOCK_AVAILABLE:
00124 return owner == null;
00125 case HAS_LOCK:
00126 return owner == thread;
00127 case WAS_NOTIFIED:
00128 return ! waiting[thread.getId()];
00129 default:
00130 throw new RuntimeException("Bad operation code");
00131 }
00132 }
00133 public String toString() {
00134 String result = (owner == null) ? "Lock:*" : "Lock:" + owner.getName();
00135 for (int i = 0; i < numThreads; i++)
00136 if (waiting[i])
00137 result += "," + i;
00138 return "<" + result + ">";
00139 }
00140 }