major refactoring of edu.berkeley.fleet.loops, includes renaming Context to CodeBag
[fleet.git] / src / edu / berkeley / fleet / loops / Program.java
index 66d10a7..7f5263b 100644 (file)
@@ -2,18 +2,23 @@ package edu.berkeley.fleet.loops;
 import edu.berkeley.fleet.api.*;
 import java.util.*;
 import java.net.*;
+import java.io.*;
 
 /**
  *  A program is a collection of CodeBags resident in a particular Memory.
  */
 public class Program {
 
-    private Ship memoryShip;
-    private Fleet fleet;
+    public final Fleet fleet;
+    public final Ship memoryShip;
+
+    private CodeBag end = null;
+
     private long leastUnallocatedAddress;
     private long startAddress;
 
-    private HashSet<CodeBag> codeBags = new HashSet<CodeBag>();
+    private ArrayList<CodeBag> codeBags = new ArrayList<CodeBag>();
+    private ArrayList<Instruction> all_instructions = new ArrayList<Instruction>();
     
     public Program(Ship memoryShip) { this(memoryShip, 0); }
     public Program(Ship memoryShip, long startAddress) {
@@ -23,51 +28,123 @@ public class Program {
         this.leastUnallocatedAddress = startAddress;
     }
 
-    public void run(FleetProcess fp, CodeBag run) {
-        System.out.println("invoking...");
-        Context ctx = new Context(fleet);
+    public Destination getCBDDestination() {
+        return memoryShip.getDock("inCBD").getDataDestination();
+    }
+
+    public long run(FleetProcess fp, CodeBag run, ShipPool pool) {
+        Ship timer    = pool.allocateShip("Timer");
+        Ship debug    = pool.allocateShip("Debug");
+        Dock debugIn  = debug.getDock("in");
+        
         LoopFactory lf;
-        fp.sendWord(memoryShip.getDock("inCBD").getDataDestination(),
-                    new BitVector(fleet.getWordWidth()).set( (run.baseAddress<<6) | run.instructions.length ));
-        System.out.println("invoked.");
+
+        CodeBag start = new CodeBag(fleet, this);
+        lf = start.loopFactory(timer.getDock("out"), 1);
+        lf.collectWord();
+        lf.sendWord(debugIn.getDataDestination());
+        lf = start.loopFactory(debugIn, 1);
+        lf.recvWord();
+        lf.deliver();
+        lf.recvWord();
+        lf.deliver();
+        start.sendWord(run.getDescriptor(), getCBDDestination());
+
+        CodeBag done  = end;
+        lf = done.loopFactory(timer.getDock("out"), 1);
+        lf.collectWord();
+        lf.sendWord(debugIn.getDataDestination());
+       
+        start.seal();
+        done.seal();
+        
+        install(fp, pool);
+        
+        MemoryUtils.putMemoryShipInDispatchMode(fp, memoryShip);
+        fp.sendWord(getCBDDestination(), start.getDescriptor().getBitVector());
+        fp.flush();
+        long now = System.currentTimeMillis();
+        System.out.println("waiting for timestamps to come back...");
+        BitVector bv1 = fp.recvWord();
+        System.out.println();
+        System.out.println("got start time (bv="+bv1+" = "+bv1.toLong()+")");
+        BitVector bv2 = fp.recvWord();
+        System.out.println("got end time (bv="+bv2+" = "+bv2.toLong()+")");
+        long ret = (bv2.toLong()-bv1.toLong());
+        long simtime = (System.currentTimeMillis()-now)/1000;
+        System.out.println("total run time = " + ret + " gate delays, " + (ret/40) + "ns (simulation time="+simtime+"sec)");
+        MemoryUtils.removeMemoryShipFromDispatchMode(fp, memoryShip);
+
+        return ret;
     }
 
-    public void install(FleetProcess fp) {
-        BitVector[] bvs = new BitVector[(int)(leastUnallocatedAddress-startAddress)];
-        int j = 0;
-        for(CodeBag cb : codeBags)
-            for(int i=0; i<cb.instructions.length; i++)
-                bvs[j++] = fleet.encodeInstruction(cb.instructions[i], memoryShip.getDock("out"));
-        System.out.println("writing... ("+bvs.length+" words)");
-        MemoryUtils.writeMem(fp, memoryShip, startAddress, bvs);
-        System.out.println("written.");
+    public void dump(String file) {
+        try {
+            FileOutputStream fos = new FileOutputStream(file);
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
+            for(int i=0; i<codeBags.size(); i++)
+                for(Instruction in : codeBags.get(i).emit())
+                    pw.println(in);
+            pw.flush();
+            pw.close();
+        } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    public CodeBag makeCodeBag(Context ctx) {
-        return makeCodeBag(ctx.emit());
+    public CodeBag getEndProgramCodeBag() {
+        if (end != null) return end;
+        end = new CodeBag(fleet, this);
+        return end;
     }
 
-    public CodeBag makeCodeBag(Instruction[] instructions) {
-        int MAX_BAG_SIZE = (1<<7)-1;
-        if (instructions.length > MAX_BAG_SIZE) {
-            System.out.println("warning: code bag size is "+instructions.length+
-                               ", which exceeds maximum of "+MAX_BAG_SIZE+
-                               "; breaking into multiple bags");
-            ArrayList<CodeBag> subBags = new ArrayList<CodeBag>();
-            for(int block=0; block<instructions.length; block+=MAX_BAG_SIZE) {
-                Instruction[] inst = new Instruction[Math.min(instructions.length-block, MAX_BAG_SIZE)];
-                System.arraycopy(instructions, block, inst, 0, inst.length);
-                subBags.add(makeCodeBag(inst));
-            }
-            throw new RuntimeException("FIXME: not done");
-
-        } else {
-            CodeBag codeBag = new CodeBag(this, instructions, leastUnallocatedAddress);
-            System.out.println("instructions.length="+instructions.length);
+    /** the provided pool should be a sibling of the one which holds this Program's instructions */
+    public void install(FleetProcess fp, ShipPool pool) {
+        for(int i=0; i<codeBags.size(); i++)
+            codeBags.get(i).emit();
+        BitVector[] bvs = new BitVector[(int)(leastUnallocatedAddress-startAddress)];
+        for(int i=0; i<bvs.length; i++) {
+            bvs[i] = fleet.encodeInstruction(all_instructions.get(i), memoryShip.getDock("out"));
+        }
+        MemoryUtils.writeMem(fp, pool, memoryShip, startAddress, bvs);
+    }
+
+    BitVector addInstructions(Instruction[] instructions) {
+
+        // CodeBags are "daisy chained" to eliminate any possibility
+        // of cloggage at the inCBD port as a result of more CBD's
+        // being dispatched than the maximum number that fit in the
+        // data fifo at that dock.
+
+        int MAX_BAG_SIZE = (1<<6)-1;
+
+        // FUZZ is an estimate of the number of instructions required
+        // to dispatch a code bag descriptor
+        int FUZZ = 4;
+
+        if (instructions.length <= MAX_BAG_SIZE) {
+            BitVector descriptor = new BitVector(fleet.getWordWidth());
+            descriptor.set( (leastUnallocatedAddress<<6) | instructions.length );
             leastUnallocatedAddress += instructions.length;
-            codeBags.add(codeBag);
-            return codeBag;
+            for(Instruction i : instructions)
+                all_instructions.add(i);
+            return descriptor;
         }
+
+        System.out.println("warning: code bag size is "+instructions.length+
+                           ", which exceeds maximum of "+MAX_BAG_SIZE+
+                           "; breaking into multiple bags");
+        
+        Instruction[] rest = new Instruction[instructions.length - (MAX_BAG_SIZE-FUZZ)];
+        System.arraycopy(instructions, MAX_BAG_SIZE-FUZZ, rest, 0, rest.length);
+        
+        DeferredBitVector restbag = addInstructions(rest);
+        CodeBag ctx = new CodeBag(fleet);
+        ctx.sendWord(restbag, getCBDDestination());
+        Instruction[] fuzz = ctx.emit();
+        if (fuzz.length > FUZZ) throw new RuntimeException("FUZZ="+FUZZ+", fuzz.length="+fuzz.length);
+        Instruction[] self = new Instruction[fuzz.length+MAX_BAG_SIZE-FUZZ];
+        System.arraycopy(instructions, 0, self, 0, MAX_BAG_SIZE-FUZZ);
+        System.arraycopy(fuzz, 0, self, MAX_BAG_SIZE-FUZZ, fuzz.length);
+        return addInstructions(self);
     }
 
 }
\ No newline at end of file