1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.api.Instruction;
7 /** this is a generic inbox which stores <32-bit items (tokens or data) */
8 public class Inbox extends InstructionPort {
10 // private data //////////////////////////////////////////////////////////////////////////////
12 /** data which has arrived from the switch fabric but not been acted on */
13 private Queue<Integer> itemsFromFabric = new LinkedList<Integer>();
15 /** a datum which has been presented to the ship */
16 //private int itemPresentedToShip;
18 /** true iff data is currently being presented to the ship */
19 private boolean itemReadyForShip = false;
21 /** if an ack token is pending, this is where it should be sent once the item is accepted */
22 private InterpreterBenkoBox ackDestinationUponAccept;
25 // protected methods /////////////////////////////////////////////////////////////////////////
27 Inbox(InterpreterShip ship, String name) { super(ship, name); }
29 /** subclasses invoke this when items arrive from the fabric */
30 protected final void addItemFromFabric(int data) {
31 itemsFromFabric.add(data);
34 /** true iff data is ready for the ship to accept */
35 protected final boolean itemReadyForShip() {
36 return itemReadyForShip;
39 private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
41 /** accpets (removes) an item -- invoked by the ship */
42 protected final int accept() {
43 if (!itemReadyForShip)
44 throw new RuntimeException("invoked accept() on an inbox which does not have items ready; your ship is buggy");
45 itemReadyForShip = false;
46 if (ackDestinationUponAccept != null) {
47 getInterpreter().sendToken(this, ackDestinationUponAccept);
48 ackDestinationUponAccept = null;
54 /** invoked by superclass */
55 protected final boolean service(Instruction.Executable instruction) {
57 // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
58 // considering additional instructions
59 if (itemReadyForShip) return false;
61 // if no instruction waiting, do nothing
62 if (instruction == null) return false;
64 // check firing conditions
65 if (instruction.tokenIn)
66 throw new RuntimeException("invalid instruction: " + instruction +
67 " (attempts to use trigger on an inbox)");
68 if (instruction.dataIn && itemsFromFabric.size()==0) return false;
70 // consume inbound data+token
71 if (instruction.dataIn) {
72 if (instruction.latch)
73 register = itemsFromFabric.remove();
75 itemsFromFabric.remove();
78 // if dataOut, present data to the ship
79 if (instruction.dataOut) {
80 itemReadyForShip = true;
82 // and make note of the fact that we need to send an ack (if requested)
83 if (instruction.tokenIn)
84 ackDestinationUponAccept = (InterpreterBenkoBox)instruction.dest;
86 } else if (instruction.tokenIn) {
88 // if dataOut is not set, we can send the data immediately
89 getInterpreter().sendToken(this, (InterpreterBenkoBox)instruction.dest);
94 protected void shutdown() {
97 Log.println(Log.red(" WARNING: a datum ("+register+") was left in inbox " +
98 this + " -- the ship has not consumed it"));
100 if (itemsFromFabric.size() > 0) {
101 Log.println(Log.red(" WARNING: you left data on the input to inbox " + this + ":"));
102 for(int i : itemsFromFabric)
103 Log.println(" " + i);
105 super.shutdown(true);