public class DinMutex extends Process implements Lock {
private static final int thinking = 0, hungry = 1, eating = 2;
Boolean fork[] = null, dirty[] = null, request[] = null;
public int myState = thinking;
public DinMutex(MsgHandler initComm) {
super(initComm);
fork = new Boolean[n]; dirty = new Boolean[n];
request = new Boolean[n];
for (int i=0; i < n; i++) {
if (myId > neighbors.get(i)) {
fork[i] = false; request[i] = true;
} else { fork[i] = true; request[i] = false; }
dirty[i] = true;
}
}
public synchronized void requestCS() {
myState = hungry;
if (haveForks()) myState = eating;
else
for (int i=0; i < n; i++)
if (request[i] && !fork[i])
sendBool(i, "Request", request[i]);
while (myState != eating) myWait();
}
public synchronized void releaseCS() {
myState = thinking;
for (int i=0; i < n; i++){
dirty[i] = true;
if (request[i]) sendBool(i, "Fork", fork[i]);
}
}
boolean haveForks() {
for (int i=0; i < n; i++)
if (!fork[i]) return false;
return true;
}
void sendBool(int nid, String tag, Boolean b) {
int dest = neighbors.get(nid);
sendMsg(dest, tag);
b = false;
}
public synchronized void handleMsg(Msg m, int src, String tag) {
int nid = neighbors.indexOf(src);
if (tag.equals("Request")) {
request[nid] = true;
if ((myState != eating) && fork[nid] && dirty[nid]) {
sendBool(nid, "Fork", fork[nid]);
if (myState == hungry)
sendBool(nid, "Request", request[nid]);
}
} else if (tag.equals("Fork")) {
fork[nid] = true; dirty[nid] = false;
if (haveForks())
myState = eating;
}
}
}