f7e5522895a9656faa138596b8c76f8b1df3478e
[fleet.git] / src / edu / berkeley / fleet / interpreter / Inbox.java
1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.sbp.util.ANSI;
3 import edu.berkeley.fleet.api.*;
4 import java.util.*;
5
6 /** this is a generic inbox which stores <32-bit items (tokens or data) */
7 public class Inbox extends InstructionBenkoBox {
8
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; }
13
14     // private data //////////////////////////////////////////////////////////////////////////////
15
16     private Packet register = null;
17
18     /** data which has arrived from the switch fabric but not been acted on */
19     private Queue<Packet> itemsFromFabric = new LinkedList<Packet>();
20
21     /** true iff data is currently being presented to the ship */
22     private boolean itemReadyForShip = false;
23
24     /** if an ack token is pending, this is where it should be sent once the item is accepted */
25     private Packet bufferedAck = null;
26
27     public boolean isInbox() { return true; }
28     public boolean isOutbox() { return false; }
29
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); }
32
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; }
39     }
40
41     //////////////////////////////////////////////////////////////////////////////
42
43     /** invoked by superclass */
44     protected final boolean service(Instruction.Executable instruction) {
45
46         // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
47         // considering additional instructions
48         if (itemReadyForShip) return false;
49
50         // if no instruction waiting, do nothing
51         if (instruction == null) return false;
52
53         // check firing conditions
54         if (instruction.tokenIn)
55             throw new RuntimeException("invalid instruction: " + instruction +
56                                        " (attempts to use trigger on an inbox)");
57
58         if (instruction.dataIn && itemsFromFabric.size()==0) return false;
59
60         // consume inbound data+token
61         if (instruction.dataIn) {
62             if (instruction.latch) {
63                 register = itemsFromFabric.remove();
64             } else {
65                 itemsFromFabric.remove();
66             }
67         }
68
69         // if dataOut, present data to the ship
70         if (instruction.dataOut) {
71             itemReadyForShip = true;
72
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);
76
77         } else if (instruction.tokenOut) {
78
79             // if dataOut is not set, we can send the data immediately
80             new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
81         }
82         return true;
83     }
84
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);
90         }
91         super.shutdown(true);
92     }
93
94 }