+++ /dev/null
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.two.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Instruction;
-import static edu.berkeley.fleet.api.Predicate.*;
-
-import java.util.*;
-
-/** anything that has a source (instruction horn) address on the switch fabric */
-abstract class InstructionDock extends InterpreterDock {
-
- public int tailged = 0;
-
- public boolean flag_a = false;
- public boolean flag_b = false;
- public boolean flag_c = false;
-
- /** the currently executing instruction */
- private Instruction executing = null;
-
- /** all instructions waiting to be executed (excludes executing) */
- private Queue<Instruction> instructions = new LinkedList<Instruction>();
-
- public int loopCounter = 0;
- private int repeatCounter = 1;
-
- InstructionDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
- super(ship, ports, bbd);
- }
-
- public void massacre() {
- executing = null;
- loopCounter = 0;
- repeatCounter = 1;
- while(instructions.size() > 0)
- instructions.remove();
- }
-
- public void kill() {
- repeatCounter = 1;
- if (executing != null) { executing = null; return; }
- if (instructions.size()==0)
- throw new RuntimeException("deadlocked " + this + " by killing too many instructions");
- instructions.remove();
- }
-
- /** an instruction arrives from the instruction horn */
- void addInstruction(Instruction instr) { instructions.add(instr); }
-
- protected void shutdown(boolean leaveAsInbox) {
- if (!(executing != null || instructions.size() > 0)) return;
- Log.println(ANSI.red(" WARNING: you left instructions on the instruction queue of port " +
- this + "; they are:"));
- if (executing != null)
- Log.println(" " + executing);
- for(Instruction i : instructions)
- Log.println(" " + i);
- }
-
- // interface to subclass ///////////////////////////////////////////////////////////////////////
-
- /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
- protected abstract boolean service(Instruction instr);
-
- protected abstract void setDataLatch(long value);
- protected abstract long peekDataLatch();
-
- protected final void service() {
- /*
- if (tailged > 0) return;
- if (executing==null && instructions.size() > 0) executing = instructions.remove();
- if (executing==null) return;
-
- boolean enabled = true;
- if (executing instanceof Instruction.PredicatedInstruction) {
- Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
- switch(ip.predicate) {
- case IgnoreOLC: enabled = true; break;
- case Default: enabled = loopCounter!=0; break;
- case FlagA: enabled = flag_a; break;
- case FlagB: enabled = flag_b; break;
- //case FlagC: enabled = ; break;
- case NotFlagA: enabled = !flag_a; break;
- case NotFlagB: enabled = !flag_b; break;
- //case NotFlagC: enabled = loopCounter==0; break;
- }
- }
-
- int oldLoopCounter = loopCounter;
- if (enabled) {
- if (executing instanceof Instruction.Set.OLC.Decrement) loopCounter = Math.max(0, loopCounter-1);
- if (executing instanceof Instruction.Counter) {
- Instruction.Counter ic = (Instruction.Counter)executing;
- if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
- setDataLatch(oldLoopCounter); // FIXME: which is correct here?
- } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
- loopCounter = (int)peekDataLatch();
- } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
- // FIXME: is there any way to load the "standing" value?
- repeatCounter = (int)peekDataLatch();
- } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
- loopCounter = ic.source;
- } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
- repeatCounter = -1;
- } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
- repeatCounter = ic.source;
- }
-
- } else if (executing instanceof Instruction.Set.Flags) {
- Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
- boolean old_c = oldLoopCounter == 0;
- boolean old_a = flag_a;
- boolean old_b = flag_b;
- flag_a =
- (((sf.flag_a & sf.FLAG_A) != 0) ? old_a : false) |
- (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
- (((sf.flag_a & sf.FLAG_B) != 0) ? old_b : false) |
- (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
- (((sf.flag_a & sf.FLAG_C) != 0) ? old_c : false) |
- (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
- flag_b =
- (((sf.flag_b & sf.FLAG_A) != 0) ? old_a : false) |
- (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
- (((sf.flag_b & sf.FLAG_B) != 0) ? old_b : false) |
- (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
- (((sf.flag_b & sf.FLAG_C) != 0) ? old_c : false) |
- (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
- } else if (executing instanceof Instruction.Set.OLC.Decrement) {
- } else {
- if (!service(executing)) return;
- }
- }
-
- if (executing==null) return;
- if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
- repeatCounter--;
- } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
- // repeat
- } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
- addInstruction(executing);
- executing = null;
- } else {
- executing = null;
- }
- */
- }
-
-
-
-}
((InstructionDock)(ic.dock)).tailged--;
} else {
- InterpreterDock sourceDock = (InterpreterDock)(((Instruction)i).dock);
+ InstructionDock sourceDock = (InstructionDock)(((Instruction)i).dock);
((InstructionDock)sourceDock).addInstruction(((Instruction)i));
}
}
public Dock getUniversalSource() { return null; }
public long getDestAddr(Path path) { throw new RuntimeException(); }
- public long getBoxInstAddr(Dock box) { return ((InterpreterDock)box).getDestAddr(); }
+ public long getBoxInstAddr(Dock box) { return ((InstructionDock)box).getDestAddr(); }
public Path getPathByAddr(Dock source, long dest) { throw new RuntimeException(); }
public Destination getDestByAddr(long dest) {
/*
import java.util.*;
abstract class InterpreterDestination extends Destination {
- public InterpreterDestination(InterpreterDock d, boolean isInstructionDestination) { super(d); }
+ public InterpreterDestination(InstructionDock d, boolean isInstructionDestination) { super(d); }
public abstract long getDestAddr();
public abstract void addDataFromFabric(Packet packet);
public abstract String getDestinationName();
package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Dock;
+import edu.berkeley.sbp.util.ANSI;
import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.api.Instruction;
+import static edu.berkeley.fleet.api.Predicate.*;
+
import java.util.*;
+/** anything that has a source (instruction horn) address on the switch fabric */
+abstract class InstructionDock extends FleetTwoDock {
-/** anything that has a destination address on the switch fabric */
-public abstract class InterpreterDock extends FleetTwoDock {
-
private final InterpreterShip ship;
private final Destination[] ports;
private final int addr = max_addr++;
- public InterpreterDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
- super(ship, bbd);
- this.ship = ship;
- this.ports = new Destination[ports.length];
- for(int i=0; i<ports.length; i++)
- this.ports[i] =
- new InterpreterDockDestination(ports[i], this, false);
- }
public Path getPath(Destination d, BitVector signal) {
throw new RuntimeException();
/** adds the included datum to the port from the switch fabric side */
public abstract void addDataFromFabric(Packet packet);
- abstract void service();
abstract void shutdown();
private class InterpreterDockDestination extends InterpreterDestination {
public String name;
public long addr = max_addr++;
- public InterpreterDockDestination(String name, InterpreterDock id, boolean isInstructionDestination) {
+ public InterpreterDockDestination(String name, InstructionDock id, boolean isInstructionDestination) {
super(id, isInstructionDestination);
this.name = name;
}
public String getDestinationName() { return name; }
- public Ship getShip() { return InterpreterDock.this.getShip(); }
- public void addDataFromFabric(Packet packet) { InterpreterDock.this.addDataFromFabric(packet); }
+ public Ship getShip() { return InstructionDock.this.getShip(); }
+ public void addDataFromFabric(Packet packet) { InstructionDock.this.addDataFromFabric(packet); }
public String toString() { return getShip()+"."+getName(); }
public long getDestAddr() { return addr; }
}
+
+ public int tailged = 0;
+
+ public boolean flag_a = false;
+ public boolean flag_b = false;
+ public boolean flag_c = false;
+
+ /** the currently executing instruction */
+ private Instruction executing = null;
+
+ /** all instructions waiting to be executed (excludes executing) */
+ private Queue<Instruction> instructions = new LinkedList<Instruction>();
+
+ public int loopCounter = 0;
+ private int repeatCounter = 1;
+
+ InstructionDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
+ super(ship, bbd);
+ this.ship = ship;
+ this.ports = new Destination[ports.length];
+ for(int i=0; i<ports.length; i++)
+ this.ports[i] =
+ new InterpreterDockDestination(ports[i], this, false);
+ }
+
+ public void massacre() {
+ executing = null;
+ loopCounter = 0;
+ repeatCounter = 1;
+ while(instructions.size() > 0)
+ instructions.remove();
+ }
+
+ public void kill() {
+ repeatCounter = 1;
+ if (executing != null) { executing = null; return; }
+ if (instructions.size()==0)
+ throw new RuntimeException("deadlocked " + this + " by killing too many instructions");
+ instructions.remove();
+ }
+
+ /** an instruction arrives from the instruction horn */
+ void addInstruction(Instruction instr) { instructions.add(instr); }
+
+ protected void shutdown(boolean leaveAsInbox) {
+ if (!(executing != null || instructions.size() > 0)) return;
+ Log.println(ANSI.red(" WARNING: you left instructions on the instruction queue of port " +
+ this + "; they are:"));
+ if (executing != null)
+ Log.println(" " + executing);
+ for(Instruction i : instructions)
+ Log.println(" " + i);
+ }
+
+ // interface to subclass ///////////////////////////////////////////////////////////////////////
+
+ /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
+ protected abstract void setDataLatch(long value);
+ protected abstract long peekDataLatch();
+
+ protected final void service() {
+ /*
+ if (tailged > 0) return;
+ if (executing==null && instructions.size() > 0) executing = instructions.remove();
+ if (executing==null) return;
+
+ boolean enabled = true;
+ if (executing instanceof Instruction.PredicatedInstruction) {
+ Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
+ switch(ip.predicate) {
+ case IgnoreOLC: enabled = true; break;
+ case Default: enabled = loopCounter!=0; break;
+ case FlagA: enabled = flag_a; break;
+ case FlagB: enabled = flag_b; break;
+ //case FlagC: enabled = ; break;
+ case NotFlagA: enabled = !flag_a; break;
+ case NotFlagB: enabled = !flag_b; break;
+ //case NotFlagC: enabled = loopCounter==0; break;
+ }
+ }
+
+ int oldLoopCounter = loopCounter;
+ if (enabled) {
+ if (executing instanceof Instruction.Set.OLC.Decrement) loopCounter = Math.max(0, loopCounter-1);
+ if (executing instanceof Instruction.Counter) {
+ Instruction.Counter ic = (Instruction.Counter)executing;
+ if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
+ setDataLatch(oldLoopCounter); // FIXME: which is correct here?
+ } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+ loopCounter = (int)peekDataLatch();
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+ // FIXME: is there any way to load the "standing" value?
+ repeatCounter = (int)peekDataLatch();
+ } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
+ loopCounter = ic.source;
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
+ repeatCounter = -1;
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
+ repeatCounter = ic.source;
+ }
+
+ } else if (executing instanceof Instruction.Set.Flags) {
+ Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
+ boolean old_c = oldLoopCounter == 0;
+ boolean old_a = flag_a;
+ boolean old_b = flag_b;
+ flag_a =
+ (((sf.flag_a & sf.FLAG_A) != 0) ? old_a : false) |
+ (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
+ (((sf.flag_a & sf.FLAG_B) != 0) ? old_b : false) |
+ (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
+ (((sf.flag_a & sf.FLAG_C) != 0) ? old_c : false) |
+ (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
+ flag_b =
+ (((sf.flag_b & sf.FLAG_A) != 0) ? old_a : false) |
+ (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
+ (((sf.flag_b & sf.FLAG_B) != 0) ? old_b : false) |
+ (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
+ (((sf.flag_b & sf.FLAG_C) != 0) ? old_c : false) |
+ (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
+ } else if (executing instanceof Instruction.Set.OLC.Decrement) {
+ } else {
+ if (!service(executing)) return;
+ }
+ }
+
+ if (executing==null) return;
+ if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
+ repeatCounter--;
+ } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
+ // repeat
+ } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
+ addInstruction(executing);
+ executing = null;
+ } else {
+ executing = null;
+ }
+ */
+ }
+
+
+
}
super(fleet, sd);
}
- private HashMap<String,InterpreterDock> ports = new HashMap<String,InterpreterDock>();
+ private HashMap<String,InstructionDock> ports = new HashMap<String,InstructionDock>();
public Iterator<Dock> iterator() { return (Iterator<Dock>)(Object)ports.values().iterator(); }
public Interpreter getInterpreter() { return (Interpreter)getFleet(); }
public abstract void service();
public final void _service() {
- for(InterpreterDock p : ports.values()) p.service();
+ for(InstructionDock p : ports.values()) p.service();
service();
}
- protected void addDock(String name, InterpreterDock port) {
+ protected void addDock(String name, InstructionDock port) {
ports.put(name, port);
}
public void shutdown() {
- for(InterpreterDock p : ports.values())
+ for(InstructionDock p : ports.values())
p.shutdown();
}
}
long value;
InterpreterDestination destination;
- public Packet(Interpreter interpreter, InterpreterDock source, long value, InterpreterDestination destination) {
+ public Packet(Interpreter interpreter, InstructionDock source, long value, InterpreterDestination destination) {
Log.data(value+"", source, (Destination)destination);
this.interpreter = interpreter;
this.value = value;
package edu.berkeley.fleet;
+// EXPERIMENTAL. Do not use.
+
// interesting primitive: an "atomic"
// take-from-fred-and-deliver-to-mary transition; you can give it
// predecessors and successors.