Opcode = Triggered:: "triggered" OpcodeBody /ws
| UnTriggered:: OpcodeBody
-OpcodeBody = ^"nop" | ^"wait" | ^"discard"
- | ^"nop+ack" | ^"wait+ack" | ^"discard+ack"
- | ^"copy" | ^"move" | ^"accept"
- | ^"copy+ack" | ^"move+ack" | ^"accept+ack"
+OpcodeBody = ^"nop" | ^"wait" | ^"discard"
+ | ^"nop+ack" | ^"wait+ack" | ^"discard+ack"
+ | ^"copy" | ^"move" | ^"accept"
+ | ^"copy+ack" | ^"move+ack" | ^"accept+ack"
+ | ^"synthesize" | ^"synthesize+ack"
Arrow = ^"->"
| ^"-[*]->"
import java.util.*;
+/** a codebag */
public class CodeBag {
private static int max_allocated_descriptor = 1;
--- /dev/null
+package edu.berkeley.fleet;
+
+import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
+import java.util.*;
+
+public class DataInbox extends Inbox {
+
+ public DataInbox(Ship ship, String name) {
+ super(ship, name);
+ }
+
+ void addDataFromFabric(int data) {
+ addItemFromFabric(data);
+ }
+
+ public boolean dataReadyForShip() {
+ return super.itemReadyForShip();
+ }
+
+ public int removeDataForShip() {
+ return super.accept();
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet;
+import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
+
+public class DataOutbox extends Outbox {
+
+ public DataOutbox(Ship ship, String name) {
+ super(ship, name);
+ }
+
+ public void addDataFromShip(int data) {
+ addItemFromShip(data);
+ }
+
+ public boolean readyForDataFromShip() {
+ return super.readyForItemFromShip();
+ }
+
+ protected void send(Port port, int data) {
+ getFleet().sendData(this, data, port);
+ }
+}
return false;
}
}
+
+ public void sendToken(Port source, Port dest) {
+ Log.token(source, dest);
+ dest.addTokenFromFabric();
+ }
+
+ public void sendData(Port source, int data, Port dest) {
+ Log.data(data+"", source, dest);
+ dest.addDataFromFabric(data);
+ }
}
public class FleetParser {
public static void main(String[] s) throws Exception {
+ for(int i=0; i<s.length; i++) {
+ if (s[i].startsWith("--color=")) {
+ String val = s[i].substring(s[i].indexOf('=')+1);
+ if (val.equals("on")) {
+ Log.ansi_color = true;
+ continue;
+ } else if (val.equals("off")) {
+ Log.ansi_color = false;
+ continue;
+ }
+ } else if (s[i].startsWith("--inboxes=")) {
+ String val = s[i].substring(s[i].indexOf('=')+1);
+ if (val.equals("configured")) {
+ DataInbox.defaultInstruction =
+ new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true);
+ continue;
+ } else if (val.equals("unconfigured")) {
+ DataInbox.defaultInstruction = null;
+ continue;
+ }
+ }
+ System.out.println("Fleeterpreter usage:");
+ System.out.println("");
+ System.out.println(" --color={on|off}");
+ System.out.println(" --inboxes={configured|unconfigured}");
+ System.exit(-1);
+ }
go(new InputStreamReader(System.in));
}
PortReference s = portReference(t.child(1));
Instruction inst = null;
if (opcodebody==null) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
- else if (opcodebody.head().equals("nop")) inst = new Instruction(s, d, count, IGNORE, false, trigger, false);
- else if (opcodebody.head().equals("wait")) inst = new Instruction(s, d, count, COPY, false, trigger, false);
- else if (opcodebody.head().equals("discard")) inst = new Instruction(s, d, count, TAKE, false, trigger, false);
- else if (opcodebody.head().equals("nop+ack")) inst = new Instruction(s, d, count, IGNORE, true, trigger, false);
- else if (opcodebody.head().equals("wait+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, false);
- else if (opcodebody.head().equals("discard+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, false);
- else if (opcodebody.head().equals("copy")) inst = new Instruction(s, d, count, COPY, false, trigger, true);
- else if (opcodebody.head().equals("copy+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, true);
- else if (opcodebody.head().equals("move")) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
- else if (opcodebody.head().equals("move+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, true);
+ else if (opcodebody.head().equals("nop")) inst = new Instruction(s, d, count, IGNORE, false, trigger, false);
+ else if (opcodebody.head().equals("synthesize")) inst = new Instruction(s, d, count, IGNORE, false, trigger, true);
+ else if (opcodebody.head().equals("synthesize+ack")) inst = new Instruction(s, d, count, IGNORE, true, trigger, true);
+ else if (opcodebody.head().equals("wait")) inst = new Instruction(s, d, count, COPY, false, trigger, false);
+ else if (opcodebody.head().equals("discard")) inst = new Instruction(s, d, count, TAKE, false, trigger, false);
+ else if (opcodebody.head().equals("nop+ack")) inst = new Instruction(s, d, count, IGNORE, true, trigger, false);
+ else if (opcodebody.head().equals("wait+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, false);
+ else if (opcodebody.head().equals("discard+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, false);
+ else if (opcodebody.head().equals("copy")) inst = new Instruction(s, d, count, COPY, false, trigger, true);
+ else if (opcodebody.head().equals("copy+ack")) inst = new Instruction(s, d, count, COPY, true, trigger, true);
+ else if (opcodebody.head().equals("move")) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
+ else if (opcodebody.head().equals("move+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, true);
else if (opcodebody.head().equals("accept")) inst = new Instruction(s, d, count, TAKE, false, trigger, true);
else if (opcodebody.head().equals("accept+ack")) inst = new Instruction(s, d, count, TAKE, true, trigger, true);
cb.add(inst);
--- /dev/null
+package edu.berkeley.fleet;
+
+import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
+import java.util.*;
+
+/** this is a generic inbox which stores <32-bit items (tokens or data) */
+public class Inbox extends InstructionPort {
+
+ static Instruction defaultInstruction =
+ new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true);
+
+
+ // private data //////////////////////////////////////////////////////////////////////////////
+
+ /** data which has arrived from the switch fabric but not been acted on */
+ private Queue<Integer> itemsFromFabric = new LinkedList<Integer>();
+
+ /** a datum which has been presented to the ship */
+ private int itemPresentedToShip;
+
+ /** true iff data is currently being presented to the ship */
+ private boolean itemReadyForShip = false;
+
+ /** if an ack token is pending, this is where it should be sent once the item is accepted */
+ private Port ackDestinationUponAccept;
+
+
+ // protected methods /////////////////////////////////////////////////////////////////////////
+
+ Inbox(Ship ship, String name) {
+ super(ship, name);
+
+ // default standing move
+ if (defaultInstruction != null)
+ addInstruction(defaultInstruction);
+ }
+
+ /** subclasses invoke this when items arrive from the fabric */
+ protected final void addItemFromFabric(int data) {
+ itemsFromFabric.add(data);
+ }
+
+ /** true iff data is ready for the ship to accept */
+ protected final boolean itemReadyForShip() {
+ return itemReadyForShip;
+ }
+
+ /** accpets (removes) an item -- invoked by the ship */
+ protected final int accept() {
+ if (!itemReadyForShip)
+ throw new RuntimeException("invoked accept() on an inbox which does not have items ready; your ship is buggy");
+ itemReadyForShip = false;
+ if (ackDestinationUponAccept != null) {
+ getFleet().sendToken(this, ackDestinationUponAccept);
+ ackDestinationUponAccept = null;
+ }
+ return itemPresentedToShip;
+ }
+
+ /** invoked by superclass */
+ protected final boolean service(Instruction instruction) {
+
+ // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
+ // considering additional instructions
+ if (itemReadyForShip) return false;
+
+ // if no instruction waiting, do nothing
+ if (instruction == null) return false;
+
+ // check firing conditions
+ if (instruction.trigger)
+ throw new RuntimeException("invalid instruction: " + instruction +
+ " (attempts to use trigger on an inbox)");
+ if (instruction.dataIn != IGNORE && itemsFromFabric.size()==0) return false;
+
+ // consume inbound data+token
+ switch(instruction.dataIn) {
+ case COPY:
+ itemPresentedToShip = itemsFromFabric.peek();
+ break;
+ case TAKE:
+ itemPresentedToShip = itemsFromFabric.remove();
+ break;
+ }
+
+ // if dataOut, present data to the ship
+ if (instruction.dataOut) {
+ itemReadyForShip = true;
+
+ // and make note of the fact that we need to send an ack (if requested)
+ if (instruction.ack)
+ ackDestinationUponAccept = instruction.destination.resolve(getShip().getFleet());
+
+ } else if (instruction.ack) {
+
+ // if dataOut is not set, we can send the data immediately
+ getFleet().sendToken(this, instruction.destination.resolve(getShip().getFleet()));
+ }
+ return true;
+ }
+
+ protected void shutdown() {
+ if (itemReadyForShip)
+ Log.println(Log.red(" WARNING: a datum ("+itemPresentedToShip+") was left in inbox " +
+ this + " -- the ship has not consumed it"));
+
+ if (itemsFromFabric.size() > 0) {
+ Log.println(Log.red(" WARNING: you left data on the input to inbox " + this + ":"));
+ for(int i : itemsFromFabric)
+ Log.println(" " + i);
+ }
+ super.shutdown(true);
+ }
+}
+++ /dev/null
-package edu.berkeley.fleet;
-
-import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
-import java.util.*;
-
-public class InboxPort extends InstructionPort {
-
- public static final Instruction defaultInstruction =
- new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true);
-
- public InboxPort(Ship ship, String name) {
- super(ship, name);
-
- // default standing move
- addInstruction(defaultInstruction);
- }
-
- // data in from the switch fabric
- private Queue<Integer> dataIn = new LinkedList<Integer>();
- public void addData(int data) { dataIn.add(data); }
- public void addToken() { throw new RuntimeException("inboxes do not accept tokens!"); }
-
- // data out to the ship
- private boolean empty = true;
- private int dataOut;
- private Port tokenDestination;
-
- public boolean empty() { return empty; }
- public int remove() {
- if (empty)
- throw new RuntimeException("called remove() on an empty() inbox");
- empty = true;
- if (tokenDestination != null) {
- Log.token(this, tokenDestination);
- tokenDestination.addToken();
- tokenDestination = null;
- }
- return dataOut;
- }
-
- public boolean service(Instruction instruction) {
-
- // if data is stuck on dataOut, wait for it to go somewhere
- if (!empty) return false;
-
- // if no instruction waiting, do nothing
- if (instruction == null) return false;
-
- // check firing conditions
- if (instruction.trigger)
- throw new RuntimeException("you cannot send a triggered instruction to an inbox!");
- if (instruction.dataIn != IGNORE && dataIn.size()==0) return false;
-
- // consume inbound data+token
- int data = 0;
- switch(instruction.dataIn) {
- case COPY:
- dataOut = dataIn.peek();
- break;
- case TAKE:
- dataOut = dataIn.remove();
- break;
-
- }
-
- if (instruction.dataOut) {
- empty = false;
- if (instruction.ack)
- tokenDestination = instruction.destination.resolve(getShip().getFleet());
-
- } else if (instruction.ack) {
- Port p = instruction.destination.resolve(getShip().getFleet());
- Log.token(this, p);
- p.addToken();
- }
- return true;
- }
-
- public void shutdown() {
- if (!empty)
- Log.println(Log.red(" WARNING: a datum ("+dataOut+") was left in inbox " + this + " -- the ship has not consumed it"));
-
- if (dataIn.size() > 0) {
- Log.println(Log.red(" WARNING: you left data on the input to inbox " + this + ":"));
- for(int i : dataIn)
- Log.println(" " + i);
- }
- super.shutdown(true);
- }
-}
package edu.berkeley.fleet;
-/** an instruction within a codebag, as specified in am10 */
+/** an instruction within a codebag, as specified in am10; this class is immutable */
public class Instruction extends Dispatchable {
public final PortReference source;
if (trigger) ret.append("triggered ");
switch(dataIn) {
case IGNORE:
- ret.append("nop");
+ ret.append(dataOut ? "synthesize" : "nop");
break;
case COPY:
ret.append(dataOut ? "copy" : "wait");
import java.util.*;
-/** common superclass for any port which can take an instruction: inbox/outbox/tokenoutbox */
+/** anything that has a source (instruction horn) address on the switch fabric */
public abstract class InstructionPort extends Port {
- public InstructionPort(Ship ship, String name) {
+ /** the currently executing instruction */
+ Instruction currentlyExecuting = null;
+
+ /** all instructions waiting to be executed (excludes currentlyExecuting) */
+ Queue<Instruction> instructions = new LinkedList<Instruction>();
+
+ /** the count field of currentlyExecuting, taking into account actions already performed */
+ int currentlyExecutingCount;
+
+ InstructionPort(Ship ship, String name) {
super(ship, name);
}
- /** add an instruction to the box */
- public void addInstruction(Instruction instr) {
+ /** an instruction arrives from the instruction horn */
+ void addInstruction(Instruction instr) {
if (currentlyExecuting != null && currentlyExecuting.count == Integer.MAX_VALUE) {
currentlyExecuting = null;
currentlyExecutingCount = 0;
}
}
- // inherited from Port
- public abstract void addData(int data);
-
- Instruction currentlyExecuting = null;
- Queue<Instruction> instructions = new LinkedList<Instruction>();
- int currentlyExecutingCount;
-
-
protected void shutdown(boolean leaveAsInbox) {
- if (leaveAsInbox) {
+ if (leaveAsInbox && DataInbox.defaultInstruction != null) {
if (currentlyExecuting == null) {
Log.println(Log.red(" WARNING: you did not leave a standing move on inbox-port " + this));
return;
- } else {
- if (currentlyExecuting.count != Integer.MAX_VALUE
- || currentlyExecuting.dataIn != Instruction.IgnoreCopyTake.TAKE
- || currentlyExecuting.ack
- || currentlyExecuting.trigger
- || !currentlyExecuting.dataOut) {
- Log.println(Log.red(" WARNING: you did not leave the correct standing move on inbox-port " + this)+
- "\n found: " + currentlyExecuting
- );
- return;
- }
+ }
+ if (currentlyExecuting.count != Integer.MAX_VALUE
+ || currentlyExecuting.dataIn != Instruction.IgnoreCopyTake.TAKE
+ || currentlyExecuting.ack
+ || currentlyExecuting.trigger
+ || !currentlyExecuting.dataOut) {
+ Log.println(Log.red(" WARNING: you did not leave the correct standing move on inbox-port " + this)+
+ "\n found: " + currentlyExecuting
+ );
+ return;
}
currentlyExecuting = null;
}
if (currentlyExecuting != null || instructions.size() > 0) {
- Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " + this + "; they are:"));
+ Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " +
+ this + "; they are:"));
if (currentlyExecuting != null)
Log.println(" " + currentlyExecuting);
for(Instruction i : instructions)
// interface to subclass ///////////////////////////////////////////////////////////////////////
- /** this will be invoked periodically; should return true to "consume" an instruction */
+ /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
protected abstract boolean service(Instruction instr);
- public void service() {
+ protected final void service() {
if (currentlyExecutingCount <= 0)
currentlyExecuting = null;
if (currentlyExecuting == null && instructions.size() > 0) {
package edu.berkeley.fleet;
+/** represents a literal; currently handled in an extremely hoakey fashion */
public class Literal {
public static class LiteralDatum extends Dispatchable {
for(int i=0; i<count; i++) {
Port port = destination.resolve(fleet);
Log.data((isCodeBag?(CodeBag.getCodeBagByDescriptor(getData())+""):(getData()+"")), null, port);
- port.addData(getData());
+ port.addDataFromFabric(getData());
}
}
public String toString() {
this.destination = destination;
}
public void dispatch(Fleet fleet) {
- destination.resolve(fleet).addToken();
+ destination.resolve(fleet).addTokenFromFabric();
}
public String toString() {
return "token -> "+destination;
public class Log {
+ public static boolean ansi_color = true;
+
public static PrintWriter log = new PrintWriter(new OutputStreamWriter(System.out));
public static void print(Object o) {
println(purple(" token: ") + (source + " -> " + purple(dest+"")));
}
- //public static String black(Object o) { return "\033[30m"+o+"\033[0m"; }
- public static String black(Object o) { return o+""; }
- //public static String clreol() { return "\033[0K"; }
public static String clreol() { return ""; }
- public static String red(Object o) { return "\033[31m"+o+"\033[0m"; }
- //public static String red(Object o) { return o+""; }
- public static String green(Object o) { return "\033[32m"+o+"\033[0m"; }
- //public static String green(Object o) { return o+""; }
- public static String yellow(Object o) { return "\033[33m"+o+"\033[0m"; }
- //public static String yellow(Object o) { return o+""; }
- //public static String blue(Object o) { return "\033[34m"+o+"\033[0m"; }
- public static String blue(Object o) { return o+""; }
- public static String purple(Object o) { return "\033[35m"+o+"\033[0m"; }
- //public static String purple(Object o) { return o+""; }
- public static String cyan(Object o) { return "\033[36m"+o+"\033[0m"; }
- //public static String cyan(Object o) { return o+""; }
- public static String invert(Object o) { return "\033[7m"+o+"\033[0m"; }
- public static String bold(Object o) { return "\033[1m"+o+"\033[0m"; }
+
+ public static String black(Object o) { if (!ansi_color) return o+""; return o+""; }
+ public static String red(Object o) { if (!ansi_color) return o+""; return "\033[31m"+o+"\033[0m"; }
+ public static String green(Object o) { if (!ansi_color) return o+""; return "\033[32m"+o+"\033[0m"; }
+ public static String yellow(Object o) { if (!ansi_color) return o+""; return "\033[33m"+o+"\033[0m"; }
+ public static String blue(Object o) { if (!ansi_color) return o+""; return o+""; }
+ public static String purple(Object o) { if (!ansi_color) return o+""; return "\033[35m"+o+"\033[0m"; }
+ public static String cyan(Object o) { if (!ansi_color) return o+""; return "\033[36m"+o+"\033[0m"; }
+ public static String invert(Object o) { if (!ansi_color) return o+""; return "\033[7m"+o+"\033[0m"; }
+ public static String bold(Object o) { if (!ansi_color) return o+""; return "\033[1m"+o+"\033[0m"; }
public static String indent(String s, String indent) {
StringBuffer ret = new StringBuffer();
--- /dev/null
+package edu.berkeley.fleet;
+import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
+
+public abstract class Outbox extends InstructionPort {
+
+ /** are we ready to accept another item from the ship? */
+ private boolean readyForItemFromShip = true;
+
+ /** data which has been presented by the ship and is waiting to depart */
+ private int itemPresentedByShip;
+
+ /** number of tokens queued on the trigger input */
+ private int triggersReceived = 0;
+
+ protected Outbox(Ship ship, String name) {
+ super(ship, name);
+ }
+
+ protected final boolean readyForItemFromShip() {
+ return readyForItemFromShip;
+ }
+
+ final void addTokenFromFabric() {
+ triggersReceived++;
+ }
+
+ protected final boolean service(Instruction instruction) {
+
+ // if no instruction waiting, do nothing
+ if (instruction == null) return false;
+
+ // check firing conditions
+ if (instruction.trigger && triggersReceived <= 0) return false;
+ if (instruction.dataIn != IGNORE && readyForItemFromShip) return false;
+
+ // consume trigger
+ if (instruction.trigger) triggersReceived--;
+
+ // consume item
+ int data = 0;
+ switch(instruction.dataIn) {
+ case COPY:
+ data = itemPresentedByShip;
+ break;
+ case TAKE:
+ data = itemPresentedByShip;
+ readyForItemFromShip = true;
+ break;
+ }
+
+ if (instruction.dataOut) {
+
+ // if item to be transmitted, send it
+ send(instruction.destination.resolve(getShip().getFleet()), data);
+ if (instruction.ack)
+ throw new RuntimeException("outboxes may not send acks!");
+
+ } else if (instruction.ack) {
+
+ // if no item was sent, we might still send an ack
+ getFleet().sendToken(this, instruction.destination.resolve(getShip().getFleet()));
+ }
+
+ return true;
+ }
+
+ /** this is invoked to transmit data; the subclass decides if it is a token or not */
+ protected abstract void send(Port port, int data);
+
+ /** subclass invokes this to add an item from the ship */
+ protected final void addItemFromShip(int data) {
+ if (!readyForItemFromShip)
+ throw new RuntimeException("tried to add an item to an outbox which was not ready! you have a buggy ship!");
+ readyForItemFromShip = false;
+ itemPresentedByShip = data;
+ }
+
+ void shutdown() {
+ if (!readyForItemFromShip)
+ Log.println(Log.red(" WARNING: you left a value ("+itemPresentedByShip+") on outbox port " + this));
+ if (triggersReceived > 0)
+ Log.println(Log.red(" WARNING: you left a token on the trigger input to port " + this));
+ super.shutdown(false);
+ }
+}
+++ /dev/null
-package edu.berkeley.fleet;
-import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
-
-public class OutboxPort extends InstructionPort {
-
- public OutboxPort(Ship ship, String name) {
- super(ship, name);
- }
-
- // data in from the ship
- private boolean empty = true;
- private int dataIn;
-
- public boolean empty() { return empty; }
-
- /** number of tokens queued on the trigger input */
- private int trigger = 0;
- public void addToken() { trigger++; }
-
- public void addData(int data) {
- if (!empty)
- throw new RuntimeException("tried to add data to a non-empty outbox! you have a buggy ship!");
- empty = false;
- dataIn = data;
- }
-
- public boolean service(Instruction instruction) {
-
- // if no instruction waiting, do nothing
- if (instruction == null) return false;
-
- // check firing conditions
- if (instruction.trigger && trigger <= 0) return false;
- if (instruction.dataIn != IGNORE && empty) return false;
-
- // consume inbound data+token
- if (instruction.trigger) trigger--;
- int data = 0;
- switch(instruction.dataIn) {
- case COPY:
- data = dataIn;
- break;
- case TAKE:
- data = dataIn;
- empty = true;
- break;
- }
-
- if (instruction.dataOut) {
- Port port = instruction.destination.resolve(getShip().getFleet());
- Log.data(data+"", this, port);
- port.addData(data);
- if (instruction.ack)
- throw new RuntimeException("outboxes may not send acks!");
-
- } else if (instruction.ack) {
- Port p = instruction.destination.resolve(getShip().getFleet());
- Log.token(this, p);
- p.addToken();
- }
-
- return true;
- }
-
- public void shutdown() {
- if (!empty)
- Log.println(Log.red(" WARNING: you left a value ("+dataIn+") on outbox port " + this));
- if (trigger > 0)
- Log.println(Log.red(" WARNING: you left a token on the trigger input to port " + this));
- super.shutdown(false);
- }
-}
package edu.berkeley.fleet;
-/** a destination on the switch fabric */
+/** anything that has a destination address on the switch fabric */
public abstract class Port {
- public final String name;
- public final Ship ship;
+ private final String name;
+ private final Ship ship;
public Port(Ship ship, String name) {
this.ship = ship;
ship.addPort(name, this);
}
- public void service() { }
+ void service() { }
- /** adds one token to the port */
- public abstract void addToken();
+ /** adds one token to the port from the switch fabric side */
+ void addTokenFromFabric() { throw new RuntimeException("this should never happen!"); }
- /** adds the included datum to the port */
- public abstract void addData(int datum);
+ /** adds the included datum to the port from the switch fabric side */
+ void addDataFromFabric(int datum) { throw new RuntimeException("this should never happen!"); }
- public Ship getShip() {
- return ship;
- }
+ /** adds one token to the port from the ship side */
+ public void addTokenFromShip() { throw new RuntimeException("this should never happen!"); }
+
+ /** adds the included datum to the port from the switch fabric side */
+ public void addDataFromShip(int datum) { throw new RuntimeException("this should never happen!"); }
+
+ public Ship getShip() { return ship; }
+
+ public Fleet getFleet() { return getShip().getFleet(); }
public String toString() { return ship+"."+name; }
- public abstract void shutdown();
+ abstract void shutdown();
}
import java.util.*;
import java.io.*;
+/** a ship, which belongs to a fleet and which may have many ports */
public abstract class Ship {
- HashMap<String,Port> ports = new HashMap<String,Port>();
+ private HashMap<String,Port> ports = new HashMap<String,Port>();
private String name;
- protected Fleet fleet;
+ private Fleet fleet;
/** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
public Ship(Fleet fleet, String name) {
service();
}
- public void addPort(String name, Port port) {
+ void addPort(String name, Port port) {
ports.put(name, port);
}
+++ /dev/null
-package edu.berkeley.fleet;
-
-public class TokenInPort extends Port {
-
- private int tokens = 0;
-
- public TokenInPort(Ship ship, String name) {
- super(ship, name);
- }
-
- public void addToken() {
- tokens++;
- }
-
- public void addData(int data) {
- throw new RuntimeException("invalid!");
- }
-
- public boolean empty() {
- return tokens==0;
- }
-
- public void remove() {
- tokens--;
- }
-
- public void shutdown() {
- if (tokens > 0)
- Log.println(Log.red(" WARNING: tokens were left on the input to " + this));
- }
-}
--- /dev/null
+package edu.berkeley.fleet;
+
+public class TokenInbox extends Inbox {
+
+ public TokenInbox(Ship ship, String name) {
+ super(ship, name);
+ }
+
+ void addTokenFromFabric() {
+ addItemFromFabric(0);
+ }
+
+ public boolean tokenReadyForShip() {
+ return super.itemReadyForShip();
+ }
+
+ public void removeTokenForShip() {
+ super.accept();
+ }
+}
+++ /dev/null
-package edu.berkeley.fleet;
-
-/** a port which outputs only tokens */
-public class TokenOutPort extends InstructionPort {
-
- private boolean empty = true;
-
- public TokenOutPort(Ship ship, String name) {
- super(ship, name);
- }
-
- public boolean empty() {
- return empty;
- }
-
- public void addToken() {
- if (!empty)
- throw new RuntimeException("tried to add data to a non-empty tokenoutbox! you have a buggy ship!");
- empty = false;
- }
-
- public boolean service(Instruction instruction) {
-
- // if no instruction waiting, do nothing
- if (instruction == null) return false;
-
- // check firing conditions
- if (instruction.trigger)
- throw new RuntimeException("you cannot send triggered instructions to token-output ports");
-
- switch(instruction.dataIn) {
- case COPY:
- if (empty) return false;
- break;
- case TAKE:
- if (empty) return false;
- empty = true;
- break;
- case IGNORE:
- if (!instruction.ack) return true;
- // fall through
- }
-
- Port port = instruction.destination.resolve(getShip().getFleet());
- Log.token(this, port);
- port.addToken();
- return true;
- }
-
- public void addData(int data) {
- throw new RuntimeException("invalid!");
- }
-
- public void shutdown() {
- if (!empty)
- Log.println(Log.red(" WARNING: you left a token on token-output port " + this));
- super.shutdown(false);
- }
-}
--- /dev/null
+package edu.berkeley.fleet;
+
+/** a port which outputs only tokens */
+public class TokenOutbox extends Outbox {
+
+ public TokenOutbox(Ship ship, String name) {
+ super(ship, name);
+ }
+
+ protected void send(Port port, int data) {
+ getFleet().sendToken(this, port);
+ }
+
+ public boolean readyForDataFromShip() {
+ return super.readyForItemFromShip();
+ }
+
+ public void addTokenFromShip() {
+ addItemFromShip(0);
+ }
+
+ public boolean readyForToken() {
+ return readyForDataFromShip();
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class BitBucketShip extends Ship {
+
+ TokenInbox token = new TokenInbox(this, "token");
+ DataInbox data = new DataInbox(this, "data");
+
+ public BitBucketShip(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (token.tokenReadyForShip()) token.removeTokenForShip();
+ if (data.dataReadyForShip()) data.removeDataForShip();
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class DebugShip extends Ship {
+
+ TokenInbox token = new TokenInbox(this, "token");
+ DataInbox data = new DataInbox(this, "data");
+
+ public DebugShip(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (token.tokenReadyForShip()) {
+ Log.println(Log.invert(" DEBUG: got a token"+Log.clreol()));
+ token.removeTokenForShip();
+ }
+ if (data.dataReadyForShip())
+ Log.println(Log.invert(" DEBUG: got a datum: " + data.removeDataForShip()+Log.clreol()));
+ }
+
+}
public class FetchShip extends Ship {
- InboxPort codebag = new InboxPort(this, "codebag");
- TokenInPort release = new TokenInPort(this, "release");
- TokenInPort revoke = new TokenInPort(this, "revoke");
- TokenOutPort done = new TokenOutPort(this, "done");
+ DataInbox codebag = new DataInbox(this, "codebag");
+ TokenInbox release = new TokenInbox(this, "release");
+ TokenInbox revoke = new TokenInbox(this, "revoke");
+ TokenOutbox done = new TokenOutbox(this, "done");
public FetchShip(Fleet fleet, String name) {
super(fleet, name);
}
public void service() {
- if (codebag.empty()) return;
- if (release.empty() && revoke.empty()) return;
- if (!done.empty()) return;
- int cbd = codebag.remove();
+ if (!codebag.dataReadyForShip()) return;
+ if (!release.tokenReadyForShip() && !revoke.tokenReadyForShip()) return;
+ if (!done.readyForToken()) return;
+ int cbd = codebag.removeDataForShip();
CodeBag cb = CodeBag.getCodeBagByDescriptor(cbd);
- if (!revoke.empty()) {
- revoke.remove();
+ if (revoke.tokenReadyForShip()) {
+ revoke.removeTokenForShip();
Log.print("revoking codebag: " + cb);
} else {
- release.remove();
+ release.removeTokenForShip();
if (cb==null)
throw new RuntimeException("bogus codebag -- this should not happen");
cb.dispatch(getFleet());
}
- done.addToken();
+ done.addTokenFromShip();
}
}
public class FifoShip extends Ship {
- InboxPort in = new InboxPort(this, "in");
- OutboxPort out = new OutboxPort(this, "out");
+ DataInbox in = new DataInbox(this, "in");
+ DataOutbox out = new DataOutbox(this, "out");
private Queue<Integer> fifo = new LinkedList<Integer>();
}
public void service() {
- if (!in.empty()) {
- fifo.add(in.remove());
+ if (in.dataReadyForShip()) {
+ fifo.add(in.removeDataForShip());
//Log.println(name + ": fifo occupancy is now " + fifo.size() + " items");
}
- if (out.empty() && fifo.size() > 0) {
- out.addData(fifo.remove());
+ if (out.readyForDataFromShip() && fifo.size() > 0) {
+ out.addDataFromShip(fifo.remove());
//Log.println(name + ": fifo occupancy is now " + fifo.size() + " items");
}
}
public class HaltShip extends Ship {
- TokenInPort in = new TokenInPort(this, "in");
+ TokenInbox in = new TokenInbox(this, "in");
public HaltShip(Fleet fleet, String name) {
super(fleet, name);
}
public void service() {
- if (in.empty()) return;
- in.remove();
+ if (!in.tokenReadyForShip()) return;
+ in.removeTokenForShip();
getFleet().halt = true;
Log.println(Log.yellow(" HALT: ====== halt ship got a token; halting the fleet ======"));
}
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class HomeworkCounter extends Ship {
+
+ private int count = -1;
+
+ TokenOutbox zero = new TokenOutbox(this, "zero");
+ TokenOutbox positive = new TokenOutbox(this, "positive");
+ DataInbox load = new DataInbox(this, "load");
+ TokenInbox ask = new TokenInbox(this, "ask");
+
+ public HomeworkCounter(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (!zero.readyForToken()) return;
+ if (!positive.readyForToken()) return;
+ if (load.dataReadyForShip()) {
+ count = load.removeDataForShip();
+ return;
+ }
+ if (ask.tokenReadyForShip()) {
+ ask.removeTokenForShip();
+ if (count > 0) {
+ count--;
+ positive.addTokenFromShip();
+ } else if (count<=0) {
+ zero.addTokenFromShip();
+ }
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.ships;
+
+import edu.berkeley.fleet.*;
+import java.util.*;
+import java.io.*;
+
+public class MemoryReadShip extends Ship {
+
+ boolean _loaded = false;
+ int _count = 0;
+ int _stride = 0;
+ int _addr = 0;
+
+ DataInbox addr = new DataInbox(this, "addr");
+ DataInbox stride = new DataInbox(this, "stride");
+ DataInbox count = new DataInbox(this, "count");
+ DataOutbox data = new DataOutbox(this, "data");
+ TokenOutbox done = new TokenOutbox(this, "done");
+
+ public MemoryReadShip(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (_count > 0) {
+ if (!data.readyForDataFromShip()) return;
+ data.addDataFromShip(_addr>=fleet.mem.length ? 0 : fleet.mem[_addr]);
+ _count--;
+ _addr += _stride;
+ if (_count==0)
+ done.addTokenFromShip();
+ } else {
+ if (count.dataReadyForShip() &&
+ addr.dataReadyForShip() &&
+ stride.dataReadyForShip() &&
+ done.readyForToken() &&
+ data.readyForDataFromShip()) {
+
+ _count = count.removeDataForShip();
+ _addr = addr.removeDataForShip();
+ _stride = stride.removeDataForShip();
+ }
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class TokenFifo extends Ship {
+
+ private int count = 0;
+
+ TokenOutbox out = new TokenOutbox(this, "out");
+ TokenInbox in = new TokenInbox(this, "in");
+
+ public TokenFifo(Fleet fleet, String name) {
+ super(fleet, name);
+ }
+
+ public void service() {
+ if (in.tokenReadyForShip()) {
+ count++;
+ in.removeTokenForShip();
+ return;
+ }
+ if (count > 0 && out.readyForToken()) {
+ count--;
+ out.addTokenFromShip();
+ }
+ }
+
+}
public class TokenSourceShip extends Ship {
- TokenOutPort out = new TokenOutPort(this, "out");
+ TokenOutbox out = new TokenOutbox(this, "out");
public TokenSourceShip(Fleet fleet, String name) {
super(fleet, name);
}
public void service() {
- if (out.empty())
- out.addToken();
+ if (out.readyForToken())
+ out.addTokenFromShip();
}
public void shutdown() {