1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.api.Instruction;
7 /** anything that has a source (instruction horn) address on the switch fabric */
8 public abstract class InstructionPort extends InterpreterBenkoBox {
10 /** the currently executing instruction */
11 Instruction.Executable currentlyExecuting = null;
13 /** all instructions waiting to be executed (excludes currentlyExecuting) */
14 Queue<Instruction.Executable> instructions = new LinkedList<Instruction.Executable>();
16 /** the count field of currentlyExecuting, taking into account actions already performed */
17 int currentlyExecutingCount;
19 InstructionPort(InterpreterShip ship, String name) {
23 public void kill(int count) {
24 if (currentlyExecuting != null) {
25 currentlyExecuting = null;
28 for(; count > 0; count--) {
29 if (instructions.size() == 0) {
30 if (currentlyExecuting == null) {
31 Log.error("You have deadlocked ship " + this +
32 " by sending a kill to an empty ififo. I feel sorry for you.");
36 instructions.remove();
41 /** an instruction arrives from the instruction horn */
42 void addInstruction(Instruction.Executable instr) {
43 instructions.add(instr);
46 protected void shutdown(boolean leaveAsInbox) {
47 if (currentlyExecuting != null || instructions.size() > 0) {
48 Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " +
49 this + "; they are:"));
50 if (currentlyExecuting != null)
51 Log.println(" " + currentlyExecuting);
52 for(Instruction.Executable i : instructions)
57 // interface to subclass ///////////////////////////////////////////////////////////////////////
59 /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
60 protected abstract boolean service(Instruction.Executable instr);
62 protected final void service() {
63 if (currentlyExecutingCount <= 0)
64 currentlyExecuting = null;
65 if (currentlyExecuting == null && instructions.size() > 0) {
66 currentlyExecuting = instructions.remove();
67 currentlyExecutingCount = currentlyExecuting.count;
68 if (currentlyExecutingCount == 0) currentlyExecutingCount = Integer.MAX_VALUE;
71 boolean ret = service(currentlyExecuting);
73 if (currentlyExecuting.recycle) {
74 currentlyExecuting = currentlyExecuting.decrementCount();
75 if (currentlyExecuting != null)
76 addInstruction(currentlyExecuting);
77 currentlyExecuting = null;
80 if (currentlyExecuting != null && currentlyExecutingCount != Integer.MAX_VALUE)
81 currentlyExecutingCount--;