1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.sbp.util.ANSI;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.api.Instruction;
6 public abstract class Outbox extends InstructionPort {
8 /** are we ready to accept another item from the ship? */
9 private boolean readyForItemFromShip = true;
11 /** data which has been presented by the ship and is waiting to depart */
12 private int itemPresentedByShip;
14 /** number of tokens queued on the trigger input */
15 private int triggersReceived = 0;
17 private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
19 protected Outbox(InterpreterShip ship, String name) {
23 public final boolean readyForItemFromShip() {
24 return readyForItemFromShip;
27 void addDataFromFabric(int datum) { addTokenFromFabric(); }
28 final void addTokenFromFabric() {
33 protected final boolean service(Instruction.Executable instruction) {
35 // if no instruction waiting, do nothing
36 if (instruction == null) return false;
38 // check firing conditions
39 if (instruction.tokenIn && triggersReceived <= 0) return false;
40 if (instruction.dataIn && readyForItemFromShip) return false;
43 if (instruction.tokenIn) triggersReceived--;
46 if (instruction.dataIn) {
47 readyForItemFromShip = true;
48 if (instruction.latch)
49 register = itemPresentedByShip;
52 if (instruction.dataOut) {
54 // if item to be transmitted, send it
55 send((InterpreterBenkoBox)instruction.dest, register);
56 if (instruction.tokenOut)
57 throw new RuntimeException("outboxes may not send acks!");
59 } else if (instruction.tokenOut) {
61 // if no item was sent, we might still send an ack
62 getInterpreter().sendToken(this, (InterpreterBenkoBox)instruction.dest);
68 /** this is invoked to transmit data; the subclass decides if it is a token or not */
69 protected abstract void send(InterpreterBenkoBox port, int data);
71 /** subclass invokes this to add an item from the ship */
72 protected final void addItemFromShip(int data) {
73 if (!readyForItemFromShip)
74 throw new RuntimeException("tried to add an item to an outbox which was not ready! you have a buggy ship!");
75 readyForItemFromShip = false;
76 itemPresentedByShip = data;
80 if (!readyForItemFromShip)
81 Log.println(ANSI.red(" WARNING: you left a value ("+itemPresentedByShip+") on outbox port " + this));
82 if (triggersReceived > 0)
83 Log.println(ANSI.red(" WARNING: you left a token on the trigger input to port " + this));
84 super.shutdown(false);