import java.util.*;
import edu.berkeley.fleet.two.*;
import edu.berkeley.fleet.api.*;
+import edu.berkeley.sbp.util.ANSI;
/** anything that has a source (instruction horn) address on the switch fabric */
class InterpreterDock extends FleetTwoDock {
boolean torpedoWaiting = false;
boolean flushing = false;
- Queue<Instruction> instructions = new LinkedList<Instruction>();
- Queue<Packet> dataPackets = new LinkedList<Packet>();
+ LinkedList<Instruction> instructions = new LinkedList<Instruction>();
+ LinkedList<Packet> dataPackets = new LinkedList<Packet>();
+
+ // HACK
+ private LinkedList<Instruction> instructionsBackedUpIntoSwitchFabric = new LinkedList<Instruction>();
+
boolean dataReadyForShip = false;
boolean readyForDataFromShip = true;
+
+ // FIXME: should be a BitVector
long dataFromShip;
boolean flagCFromShip;
requeueStageHasTailInstruction = false;
instructions.clear();
dataPackets.clear();
+ instructionsBackedUpIntoSwitchFabric.clear();
dataReadyForShip = false;
readyForDataFromShip = true;
torpedoWaiting = false;
public String toString() { return getDock()+":i"; }
public void addDataFromFabric(Packet p) {
if (p.isToken()) {
- if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
+ if (instructionsBackedUpIntoSwitchFabric.size()!=0)
+ throw new RuntimeException("torpedo arrived while instructions were backed up into switch fabric");
+ if (torpedoWaiting) throw new RuntimeException("two torpedoes collided at dock "+this);
torpedoWaiting = true;
return;
}
Instruction inst =
getInterpreter().decodeInstruction(p.getValue(),
InterpreterDock.this /* this is wrong, but harmless */);
-
- // FIXME: this is a bit too conservative. In theory,
- // it's okay to dispatch new instructions to the dock
- // as long as we know that it will reach the updating
- // state without any further input from the outside
- // world -- ie that the instructions which remain to
- // be executed before the requeue stage transitions to
- // the updating state are all "non-blocking" (no moves
- // with Ti=1 or Di=1)
- if (requeueStageInCirculatingState || requeueStageHasTailInstruction)
- throw new RuntimeException("An instruction arrived while the requeue stage was circulating -- "+
- "this means that instructions have backed up into "+
- "the switch fabric, which nearly always risks deadlock! "+
- "Fix your program!"+
- "\n dock: " + InterpreterDock.this +
- "\n instruction: " + inst
- );
- if (inst instanceof Instruction.Tail) {
- requeueStageHasTailInstruction = true;
- return;
- }
- instructions.add(inst);
+ addInstruction(inst);
}
};
public InterpreterDestination dataDestination = new InterpreterDestination(this) {
public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
+ boolean trace = false;
+
+ private void addInstruction(Instruction inst) {
+ if (requeueStageInCirculatingState || requeueStageHasTailInstruction) {
+ // GROSS HACK
+ instructionsBackedUpIntoSwitchFabric.add(inst);
+ return;
+ }
+ if (inst instanceof Instruction.Tail) {
+ requeueStageHasTailInstruction = true;
+ return;
+ }
+ instructions.add(inst);
+ }
+
protected final void service() {
if (dataReadyForShip || flushing) return;
} else if (instructions.peek() instanceof Instruction.Abort) {
requeueStageInCirculatingState = false;
+ // HACK
+ while (instructionsBackedUpIntoSwitchFabric.size()!=0) {
+ Instruction i = instructionsBackedUpIntoSwitchFabric.remove();
+ addInstruction(i);
+ instructionsBackedUpIntoSwitchFabric.clear();
+ }
break;
} else if (instructions.peek() instanceof Instruction.Flush) {
Instruction.Shift shift = (Instruction.Shift)instructions.peek();
for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--)
dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth()));
+ BitVector shift_immediate = shift.immediate.getBitVector();
for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--)
- dataLatch.set(i, shift.immediate.get(i));
+ dataLatch.set(i, shift_immediate.get(i));
break;
} else if (instructions.peek() instanceof Instruction.Set) {
case Immediate: olc = (int)set.immediate; break;
case DataLatch:
olc = 0;
- for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
+ for(int i=0; i<getShip().getFleet().getWordWidth(); i++)
if (dataLatch.get(i))
olc |= (1 << i);
break;
protected long peekDataForShip() {
if (!dataReadyForShip)
throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false");
- BitVector bv = dataLatch;
- long val = 0;
- for(int i=0; i<bv.length(); i++)
- if (bv.get(i))
- val |= (1L << i);
- return val;
+ return dataLatch.toLong();
}
protected void addDataFromShip(long data) { addDataFromShip(data, false); }
protected void addDataFromShip(long data, boolean pending_flag_c) {
dataFromShip = data;
flagCFromShip = pending_flag_c;
}
+
+
+ // Debugging //////////////////////////////////////////////////////////////////////////////
+
+ public void dumpState() {
+ if (instructions.size()==0 &&
+ dataPackets.size()==0 &&
+ instructionsBackedUpIntoSwitchFabric.size()==0 &&
+ !requeueStageHasTailInstruction &&
+ !requeueStageInCirculatingState &&
+ !torpedoWaiting &&
+ !flushing &&
+ !dataReadyForShip &&
+ readyForDataFromShip)
+ return;
+ System.out.println("state of "+ANSI.green(this)+": "+
+ (ilc==1?"":("[ilc="+(ilc==-1 ? "*" : (ilc+""))+"] "))+
+ (olc==1?"":("[olc="+olc+"] "))+
+ (flag_a?"[a] ":"")+
+ (flag_b?"[b] ":"")+
+ (flag_c?"[c] ":"")+
+ (flag_d?"[d] ":"")+
+ (requeueStageInCirculatingState?"[recirculating] ":"")+
+ (requeueStageHasTailInstruction?"[tail waiting] ":"")+
+ (torpedoWaiting?"[torpedo waiting] ":"")+
+ (flushing?"[flushing] ":"")
+ );
+ if (!readyForDataFromShip)
+ System.out.println(ANSI.cyan(" ship has proffered: " + dataFromShip));
+ if (dataReadyForShip)
+ System.out.println(ANSI.cyan(" waiting for ship to accept: " + dataLatch.toLong()));
+ for(Instruction i : instructions)
+ System.out.println(ANSI.red(" "+i));
+ for(Instruction i : instructionsBackedUpIntoSwitchFabric)
+ System.out.println(ANSI.red(ANSI.bold(" "+i+" BACKED UP")));
+ for(Packet p : dataPackets)
+ System.out.println(ANSI.cyan(" "+p));
+ }
+
}