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 class Outbox extends InstructionBenkoBox {
8 /** are we ready to accept another item from the ship? */
9 private boolean readyForDataFromShip = false;
10 private boolean haveDataFromShip = false;
12 /** data which has been presented by the ship and is waiting to depart */
13 private long itemPresentedByShip;
15 /** number of tokens queued on the trigger input */
16 private int triggersReceived = 0;
18 /** the latched value */
19 private long register;
21 public boolean isInbox() { return false; }
22 public boolean isOutbox() { return true; }
23 public Outbox(InterpreterShip ship, String name) { this(ship, name, new String[] { "" }); }
24 public Outbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
26 protected final boolean service(Instruction.Executable instruction) {
28 // if no instruction waiting, do nothing
29 if (instruction == null) return false;
31 // check firing conditions
32 if (instruction.tokenIn && triggersReceived <= 0) return false;
33 if (instruction.dataIn) {
34 if (!haveDataFromShip) { readyForDataFromShip = true; return false; }
38 if (instruction.tokenIn) triggersReceived--;
41 if (instruction.dataIn) {
42 haveDataFromShip = false;
43 if (instruction.latch)
44 register = itemPresentedByShip;
47 if (instruction.dataOut) {
49 // if item to be transmitted, send it
50 new Packet(getInterpreter(), this, register, (InterpreterDestination)instruction.dest).send();
51 if (instruction.tokenOut)
52 throw new RuntimeException("outboxes may not send acks!");
54 } else if (instruction.tokenOut) {
56 // if no item was sent, we might still send an ack
57 new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
63 public final boolean readyForDataFromShip() { return readyForDataFromShip; }
64 public void addDataFromShip(long data) { addItemFromShip(data); }
65 public void addDataFromFabric(Packet packet) { triggersReceived++; }
67 /** subclass invokes this to add an item from the ship */
68 protected final void addItemFromShip(long data) {
69 if (!readyForDataFromShip)
70 throw new RuntimeException("tried to add an item to an outbox which was not ready! you have a buggy ship!");
71 readyForDataFromShip = false;
72 haveDataFromShip = true;
73 itemPresentedByShip = data;
78 Log.println(ANSI.red(" WARNING: you left a value ("+itemPresentedByShip+") on outbox port " + this));
79 if (triggersReceived > 0)
80 Log.println(ANSI.red(" WARNING: you left a token on the trigger input to port " + this));
81 super.shutdown(false);