1 package edu.berkeley.fleet.loops;
4 import edu.berkeley.fleet.two.*;
5 import edu.berkeley.fleet.api.*;
6 import edu.berkeley.fleet.api.Instruction.*;
7 import edu.berkeley.fleet.api.Instruction.Set;
8 import edu.berkeley.fleet.api.Instruction.Set.*;
9 import static edu.berkeley.fleet.util.BitManipulations.*;
12 // QUESTION: does each dock mentioned by a context have a linear chain
13 // of loops, or can it branch?
15 // - or should we use "sub-contexts" for that
16 // - advantage: it lets us convey the fact that a bunch of loops are dispatched together
17 // - should loops have an "invoke context" opcode?
20 * A CodeBag is a collection of Loops which obey these rules:
22 * - A CodeBag has exclusive control of all docks mentioned by any of its Loops.
23 * - A CodeBag includes a "starting loop" for every dock it mentions.
24 * - When a CodeBag is spawned, it starts the "starting loop" on all of its docks.
25 * - A loop may or may not have a successor.
26 * - Control may transfer only two ways:
27 * - If a loop has a successor, control will transfer to the successor when the loop finishes.
28 * - A loop may explicitly transfer control to another loop via abortAndInvoke(). The
29 * invoked loop must belong to the same Dock and the same CodeBag.
30 * - A CodeBag finishes when all of its docks have finished executing a loop with no successor.
33 * - A Move instruction is a blocking instruction if either its tokenIn or dataIn bits are set.
34 * - All other instructions are non-blocking.
35 * - A dock is quiescent if its instruction ring is empty.
36 * - A dock is pre-quiescent if
37 * - all instructions which remain in the target dock's instruction
38 * fifo are nonblocking instructions,
39 * - either the docks' OLC=0 or all instructions which remain
40 * in its instruction fifo are one-shot instructions
41 * - after executing these remaining instructions, the dock's hatch is open
45 * SF works works @diff ok for non size ships
46 * Dispatch Method Crossings @inbox? docks? tail call? limit consumed
47 * ------------------------------------------------------------------------------------------
49 * Inline 0 Y N N Small None
51 * Inline literals 1 N Y Y Tiny None
54 * Send CBD to 2+ N Y Y None None (mem ship)
57 * Send token to 3+ Y Y Y None One Output Dock
58 * assistant outbox first
60 * Release from FIFO 2 Y Y Y Med 1x FIFO, but can be shared
64 public class CodeBag {
66 public final Fleet fleet;
68 private Program program = null;
69 private BitVector descriptor = null;
70 public DeferredBitVector getDescriptor() {
71 return new DeferredBitVector() {
72 public BitVector getBitVector() {
73 if (program==null) throw new RuntimeException();
79 LinkedHashMap<Dock,LoopFactory> startupLoopFactories = new LinkedHashMap<Dock,LoopFactory>();
80 ArrayList<LoopFactory> loopFactories = new ArrayList<LoopFactory>();
82 // FIXME: currently not used
83 private boolean sealed = false;
84 public boolean isSealed() { return sealed; }
87 for(LoopFactory lf : loopFactories) lf.flush_pending();
89 if (program!=null) descriptor = program.addInstructions(emit());
92 public CodeBag(Fleet fleet) { this(fleet, null); }
93 public CodeBag(Program prog) { this(prog.fleet, prog); }
94 public CodeBag(Fleet fleet, Program prog) {
99 public LoopFactory loopFactory(Dock dock, int count) { return loopFactory(dock, count, count==0); }
100 public LoopFactory loopFactory(Dock dock, int count, boolean torpedoable) {
101 LoopFactory ret = startupLoopFactories.get(dock);
102 if (ret == null) return new LoopFactory(this, dock, count, torpedoable);
103 while (ret.getNext()!=null)
105 return ret.makeNext(count, torpedoable);
108 boolean autoflush = false;
109 public void setAutoflush(boolean a) { this.autoflush = a; }
110 public boolean getAutoflush() { return autoflush; }
112 public void emit(ArrayList<Instruction> ic) {
114 for(LoopFactory lf : startupLoopFactories.values())
118 private LoopFactory hack = null;
119 public void sendTorpedo(Dock dock) {
120 if (hack==null) hack = loopFactory(fleet.getShip("Timer",0).getDock("out"), 1);
121 hack.sendToken(dock.getInstructionDestination());
123 public void sendWord(DeferredBitVector bv, Destination dest) {
124 // problem: this isn't actually atomic -- two uncoordinated
125 // actors might invoke these commands at the same time
126 if (hack==null) hack = loopFactory(fleet.getShip("Timer",0).getDock("out"), 1);
131 public Instruction[] emit() {
132 ArrayList<Instruction> ic = new ArrayList<Instruction>();
134 return (Instruction[])ic.toArray(new Instruction[0]);
137 public void dispatch(FleetProcess fp) { dispatch(fp, false); }
138 public void dispatch(FleetProcess fp, boolean flushWhenDone) {
139 ArrayList<Instruction> ai;
140 emit(ai = new ArrayList<Instruction>());
141 for(Instruction ins : ai)
142 fp.sendInstruction(ins);
143 if (flushWhenDone) fp.flush();
146 public void append(CodeBag ctx) {
147 if (sealed) throw new RuntimeException("already sealed");
148 // how to handle ship pools?
149 throw new RuntimeException("not implemented");