added am10 inbox/outbox support
[fleet.git] / src / edu / berkeley / fleet / InboxPort.java
1 package edu.berkeley.fleet;
2
3 import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*;
4 import java.util.*;
5
6 public class InboxPort extends InstructionPort {
7
8     public InboxPort(Ship ship, String name) {
9         super(ship, name);
10
11         // default standing move
12         addInstruction(new Instruction(null,
13                                        null,
14                                        Integer.MAX_VALUE,
15                                        TAKE,
16                                        false,
17                                        false,
18                                        true
19                                        ));
20     }
21
22     // data in from the switch fabric
23     private Queue<Integer> dataIn = new LinkedList<Integer>();
24     public void addData(int data) { dataIn.add(data); }
25     public void addToken() { throw new RuntimeException("inboxes do not accept tokens!"); }
26
27     // data out to the ship
28     private boolean empty = true;
29     private int dataOut;
30     private Port tokenDestination;
31
32     public boolean empty() { return empty; }
33     public int remove() {
34         if (empty)
35             throw new RuntimeException("called remove() on an empty() inbox");
36         empty = true;
37         if (tokenDestination != null) {
38             Log.token(this, tokenDestination);
39             tokenDestination.addToken();
40         }
41         return dataOut;
42     }
43
44     public boolean service(Instruction instruction) {
45
46         // if data is stuck on dataOut, wait for it to go somewhere
47         if (!empty) return false;
48
49         // if no instruction waiting, do nothing
50         if (instruction == null) return false;
51
52         // check firing conditions
53         if (instruction.trigger)
54             throw new RuntimeException("you cannot send a triggered instruction to an inbox!");
55         if (instruction.dataIn != IGNORE && dataIn.size()==0) return false;
56
57         // consume inbound data+token
58         int data = 0;
59         switch(instruction.dataIn) {
60             case COPY:
61                 dataOut = dataIn.peek();
62                 break;
63             case TAKE:
64                 dataOut = dataIn.remove();
65                 break;
66         }
67
68         if (instruction.dataOut) {
69             empty = false;
70             if (instruction.ack)
71                 tokenDestination = instruction.destination.resolve(getShip().getFleet());
72
73         } else if (instruction.ack) {
74             Port p = instruction.destination.resolve(getShip().getFleet());
75             Log.token(this, p);
76             p.addToken();
77         }
78         return true;
79     }
80 }