update to AM15
[fleet.git] / src / edu / berkeley / fleet / InstructionPort.java
1 package edu.berkeley.fleet;
2
3 import java.util.*;
4
5 /** anything that has a source (instruction horn) address on the switch fabric */
6 public abstract class InstructionPort extends Port {
7
8     /** the currently executing instruction */
9     Instruction currentlyExecuting = null;
10
11     /** all instructions waiting to be executed (excludes currentlyExecuting) */
12     Queue<Instruction> instructions = new LinkedList<Instruction>();
13
14     /** the count field of currentlyExecuting, taking into account actions already performed */
15     int currentlyExecutingCount;
16
17     InstructionPort(Ship ship, String name) {
18         super(ship, name);
19     }
20
21     /** an instruction arrives from the instruction horn */
22     void addInstruction(Instruction instr) {
23         if (currentlyExecuting != null && currentlyExecuting.count == Integer.MAX_VALUE) {
24             currentlyExecuting = null;
25             currentlyExecutingCount = 0;
26         }
27         if (currentlyExecuting == null) {
28             currentlyExecuting = instr;
29             currentlyExecutingCount = currentlyExecuting.count;
30         } else {
31             instructions.add(instr);
32         }
33     }
34
35     protected void shutdown(boolean leaveAsInbox) {
36         if (leaveAsInbox && DataInbox.defaultInstruction != null) {
37             if (currentlyExecuting == null) {
38                 Log.println(Log.red(" WARNING: you did not leave a standing move on inbox-port " + this));
39                 return;
40             }
41             /*
42             if (currentlyExecuting.count != Integer.MAX_VALUE
43                 || currentlyExecuting.dataIn != Instruction.IgnoreCopyTake.TAKE
44                 || currentlyExecuting.ack
45                 || currentlyExecuting.trigger
46                 || !currentlyExecuting.dataOut) {
47                 Log.println(Log.red(" WARNING: you did not leave the correct standing move on inbox-port " + this)+
48                             "\n            found:    " + currentlyExecuting
49                             );
50                 return;
51             }
52             */
53             currentlyExecuting = null;
54         }
55         if (currentlyExecuting != null || instructions.size() > 0) {
56             Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " +
57                                 this + "; they are:"));
58             if (currentlyExecuting != null)
59                 Log.println("   " + currentlyExecuting);
60             for(Instruction i : instructions)
61                 Log.println("   " + i);
62         }
63     }
64
65     // interface to subclass ///////////////////////////////////////////////////////////////////////
66
67     /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
68     protected abstract boolean service(Instruction instr);
69
70     protected final void service() {
71         if (currentlyExecutingCount <= 0)
72             currentlyExecuting = null;
73         if (currentlyExecuting == null && instructions.size() > 0) {
74             currentlyExecuting = instructions.remove();
75             currentlyExecutingCount = currentlyExecuting.count;
76         }
77         boolean ret = service(currentlyExecuting);
78         if (ret && currentlyExecuting != null && currentlyExecutingCount != Integer.MAX_VALUE)
79             currentlyExecutingCount--;
80     }
81
82
83 }