updated to AM14, AM15
[fleet.git] / src / edu / berkeley / fleet / interpreter / Inbox.java
1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.api.Instruction;
4
5 import java.util.*;
6
7 /** this is a generic inbox which stores <32-bit items (tokens or data) */
8 public class Inbox extends InstructionPort {
9
10     // private data //////////////////////////////////////////////////////////////////////////////
11
12     /** data which has arrived from the switch fabric but not been acted on */
13     private Queue<Integer> itemsFromFabric = new LinkedList<Integer>();
14
15     /** a datum which has been presented to the ship */
16     //private int itemPresentedToShip;
17
18     /** true iff data is currently being presented to the ship */
19     private boolean itemReadyForShip = false;
20
21     /** if an ack token is pending, this is where it should be sent once the item is accepted */
22     private InterpreterBenkoBox ackDestinationUponAccept;
23
24
25     // protected methods /////////////////////////////////////////////////////////////////////////
26
27     Inbox(InterpreterShip ship, String name) { super(ship, name); }
28
29     /** subclasses invoke this when items arrive from the fabric */
30     protected final void addItemFromFabric(int data) {
31         itemsFromFabric.add(data);
32     }
33
34     /** true iff data is ready for the ship to accept */
35     protected final boolean itemReadyForShip() {
36         return itemReadyForShip;
37     }
38
39     private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
40
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;
49         }
50         return register;
51     }
52
53     int register = 0;
54     /** invoked by superclass */
55     protected final boolean service(Instruction.Executable instruction) {
56
57         // if data is stuck on itemPresentedToShip, wait for it to go somewhere before
58         // considering additional instructions
59         if (itemReadyForShip) return false;
60
61         // if no instruction waiting, do nothing
62         if (instruction == null) return false;
63
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;
69
70         // consume inbound data+token
71         if (instruction.dataIn) {
72             if (instruction.latch)
73                 register = itemsFromFabric.remove();
74             else
75                 itemsFromFabric.remove();
76         }
77
78         // if dataOut, present data to the ship
79         if (instruction.dataOut) {
80             itemReadyForShip = true;
81
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;
85
86         } else if (instruction.tokenIn) {
87
88             // if dataOut is not set, we can send the data immediately
89             getInterpreter().sendToken(this, (InterpreterBenkoBox)instruction.dest);
90         }
91         return true;
92     }
93
94     protected void shutdown() {
95         /*
96         if (itemReadyForShip)
97             Log.println(Log.red(" WARNING: a datum ("+register+") was left in inbox " +
98                                 this + " -- the ship has not consumed it"));
99         */              
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);
104         }
105         super.shutdown(true);
106     }
107 }