putMemoryShipInDispatchMode() now puts both out and inCBD in infinite-recieve mode
[fleet.git] / src / edu / berkeley / fleet / loops / Program.java
1 package edu.berkeley.fleet.loops;
2 import edu.berkeley.fleet.api.*;
3 import java.util.*;
4 import java.net.*;
5
6 /**
7  *  A program is a collection of CodeBags resident in a particular Memory.
8  */
9 public class Program {
10
11     private Ship memoryShip;
12     private Fleet fleet;
13     private long leastUnallocatedAddress;
14     private long startAddress;
15
16     private HashSet<CodeBag> codeBags = new HashSet<CodeBag>();
17     
18     public Program(Ship memoryShip) { this(memoryShip, 0); }
19     public Program(Ship memoryShip, long startAddress) {
20         this.fleet = memoryShip.getFleet();
21         this.memoryShip = memoryShip;
22         this.startAddress = startAddress;
23         this.leastUnallocatedAddress = startAddress;
24     }
25
26     public void run(FleetProcess fp, CodeBag run) {
27         System.out.println("invoking...");
28         Context ctx = new Context(fleet);
29         LoopFactory lf;
30         fp.sendWord(memoryShip.getDock("inCBD").getDataDestination(),
31                     new BitVector(fleet.getWordWidth()).set( (run.baseAddress<<6) | run.instructions.length ));
32         System.out.println("invoked.");
33     }
34
35     public void install(FleetProcess fp) {
36         BitVector[] bvs = new BitVector[(int)(leastUnallocatedAddress-startAddress)];
37         int j = 0;
38         for(CodeBag cb : codeBags)
39             for(int i=0; i<cb.instructions.length; i++)
40                 bvs[j++] = fleet.encodeInstruction(cb.instructions[i], memoryShip.getDock("out"));
41         System.out.println("writing... ("+bvs.length+" words)");
42         MemoryUtils.writeMem(fp, memoryShip, startAddress, bvs);
43         System.out.println("written.");
44     }
45
46     public CodeBag makeCodeBag(Context ctx) {
47         return makeCodeBag(ctx.emit());
48     }
49
50     public CodeBag makeCodeBag(Instruction[] instructions) {
51         int MAX_BAG_SIZE = (1<<7)-1;
52         if (instructions.length > MAX_BAG_SIZE) {
53             System.out.println("warning: code bag size is "+instructions.length+
54                                ", which exceeds maximum of "+MAX_BAG_SIZE+
55                                "; breaking into multiple bags");
56             ArrayList<CodeBag> subBags = new ArrayList<CodeBag>();
57             for(int block=0; block<instructions.length; block+=MAX_BAG_SIZE) {
58                 Instruction[] inst = new Instruction[Math.min(instructions.length-block, MAX_BAG_SIZE)];
59                 System.arraycopy(instructions, block, inst, 0, inst.length);
60                 subBags.add(makeCodeBag(inst));
61             }
62             throw new RuntimeException("FIXME: not done");
63
64         } else {
65             CodeBag codeBag = new CodeBag(this, instructions, leastUnallocatedAddress);
66             System.out.println("instructions.length="+instructions.length);
67             leastUnallocatedAddress += instructions.length;
68             codeBags.add(codeBag);
69             return codeBag;
70         }
71     }
72
73 }