1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.sbp.util.ANSI;
3 import edu.berkeley.fleet.api.*;
6 /** this is a generic inbox which stores <32-bit items (tokens or data) */
7 public class Inbox extends InstructionBenkoBox {
9 public boolean dataReadyForShip() { return itemReadyForShip; }
10 public Packet removePacketForShip() { remove(); return register; }
11 public Packet peekPacketForShip() { return register; }
12 public long removeDataForShip() { remove(); return register.value; }
14 // private data //////////////////////////////////////////////////////////////////////////////
16 private Packet register = null;
18 /** data which has arrived from the switch fabric but not been acted on */
19 private Queue<Packet> itemsFromFabric = new LinkedList<Packet>();
21 /** true iff data is currently being presented to the ship */
22 private boolean itemReadyForShip = false;
24 /** if an ack token is pending, this is where it should be sent once the item is accepted */
25 private Packet bufferedAck = null;
27 public boolean isInbox() { return true; }
28 public boolean isOutbox() { return false; }
30 public Inbox(InterpreterShip ship, String name) { super(ship, name, new String[] { "" }); }
31 public Inbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
33 public void addDataFromFabric(Packet packet) { itemsFromFabric.add(packet); }
34 private void remove() {
35 if (!itemReadyForShip)
36 throw new RuntimeException("invoked accept() on an inbox which does not have items ready; your ship is buggy");
37 itemReadyForShip = false;
38 if (bufferedAck != null) { bufferedAck.send(); bufferedAck = null; }
41 //////////////////////////////////////////////////////////////////////////////
43 /** invoked by superclass */
44 protected final boolean service(Instruction.Executable instruction) {
46 // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
47 // considering additional instructions
48 if (itemReadyForShip) return false;
50 // if no instruction waiting, do nothing
51 if (instruction == null) return false;
53 // check firing conditions
54 if (instruction.tokenIn)
55 throw new RuntimeException("invalid instruction: " + instruction +
56 " (attempts to use trigger on an inbox)");
58 if (instruction.dataIn && itemsFromFabric.size()==0) return false;
60 // consume inbound data+token
61 if (instruction.dataIn) {
62 if (instruction.latch) {
63 register = itemsFromFabric.remove();
65 itemsFromFabric.remove();
69 // if dataOut, present data to the ship
70 if (instruction.dataOut) {
71 itemReadyForShip = true;
73 // and make note of the fact that we need to send an ack (if requested)
74 if (instruction.tokenOut)
75 bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest);
77 } else if (instruction.tokenOut) {
79 // if dataOut is not set, we can send the data immediately
80 new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
85 protected void shutdown() {
86 if (itemsFromFabric.size() > 0) {
87 Log.println(ANSI.red(" WARNING: you left data on the input to inbox " + this + ":"));
88 for(Packet p : itemsFromFabric)
89 Log.println(" " + p.value);