checkpoint
[fleet.git] / src / edu / berkeley / fleet / Fleet.java
1 package edu.berkeley.fleet;
2
3 import java.lang.reflect.*;
4 import edu.berkeley.sbp.chr.*;
5 import edu.berkeley.sbp.misc.*;
6 import edu.berkeley.sbp.meta.*;
7 import edu.berkeley.sbp.bind.*;
8 import edu.berkeley.sbp.util.*;
9 import java.util.*;
10 import java.io.*;
11 import edu.berkeley.fleet.ships.*;
12
13 public class Fleet {
14
15     /** some "halt ship" can turn this on to stop the interpreter */
16     public boolean halt = false;
17
18     public int[] mem = new int[0];
19     public ArrayList<String> imports = new ArrayList<String>();
20
21     public ArrayList<Ship> shiplist = new ArrayList<Ship>();
22     public HashMap<String,Ship> ships = new HashMap<String,Ship>();
23
24     public void go() {
25         while(!halt)
26             for(Ship ship : ships.values())
27                 for(int j=0; j<10; j++)
28                     ship._service();
29
30         // run the ships a bit longer for good measure
31         for(int i=0; i<100; i++)
32             for(Ship ship : ships.values())
33                 for(int j=0; j<10; j++)
34                     ship._service();
35
36         // check the state of the ships
37         for(Ship ship : ships.values())
38             ship.shutdown();
39
40         Log.println(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
41     }
42
43     public void dumpMem() {
44         Log.print(Log.cyan("  MEMORY: "));
45         for(int i=0; i<mem.length; i++) {
46             if ((i%10)==0 && i!=0) Log.print(Log.cyan("          "));
47             Log.print(Log.cyan(mem[i] + " "));
48             if ((i%10)==9 && i!=mem.length-1) Log.println("");
49         }
50         Log.println();
51     }
52
53     public void writeMem(int addr, int data) {
54         if (addr >= mem.length) {
55             int[] mem2 = new int[addr*2+1];
56             System.arraycopy(mem, 0, mem2, 0, mem2.length);
57             mem = mem2;
58         }
59         mem[addr] = data;
60     }
61
62     public Ship getShip(String name) {
63         Ship s = ships.get(name);
64         if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
65         return s;
66     }
67
68     boolean tryCreate(String classname, String shipname) {
69         try {
70             Class c = Class.forName(classname);
71             Constructor con = c.getConstructor(new Class[] { Fleet.class, String.class });
72             con.newInstance(new Object[] { this, shipname });
73             return true;
74         } catch (Exception e) {
75             return false;
76         }
77     }
78
79     public void sendToken(Port source, Port dest) {
80         Log.token(source, dest);
81         dest.addTokenFromFabric();
82     }
83
84     public void sendData(Port source, int data, Port dest) {
85         Log.data(data+"", source, dest);
86         dest.addDataFromFabric(data);
87     }
88
89     public void dumpFabric(boolean quiet) {
90         // FIXME: this is really ugly: the order of port declarations in
91         //        the XXXShip.java file must match the order in the .balsa file!
92
93         ArrayList instructionports = new ArrayList<Port>();
94         for(Ship ship : shiplist)
95             for(Port port : ship.portlist)
96                 if (!(port.getName().equals("out") && port.getShip() instanceof DebugShip))
97                     instructionports.add(port);
98         FabricTree instructions =
99             new FabricTree((Port[])instructionports.toArray(new Port[0]),
100                            "horn",
101                            "instruction");
102
103         ArrayList inputports = new ArrayList<Port>();
104         for(Ship ship : shiplist)
105             for(Port port : ship.portlist)
106                 if (!(port.getName().equals("out") && port.getShip() instanceof DebugShip))
107                     inputports.add(port);
108         FabricTree inputs =
109             new FabricTree((Port[])inputports.toArray(new Port[0]),
110                            "horn",
111                            "dest");
112
113         ArrayList outputports = new ArrayList<Port>();
114         for(Ship ship : shiplist)
115             for(Port port : ship.portlist)
116                 if (!(port.getName().equals("out") && port.getShip() instanceof DebugShip))
117                     outputports.add(port);
118         FabricTree outputs =
119             new FabricTree((Port[])outputports.toArray(new Port[0]),
120                            "funnel",
121                            "source");
122
123         if (quiet) return;
124         System.out.println("import [balsa.sim.portio]");
125         System.out.println("import [xbit]");
126         System.out.println("import [funnel]");
127         System.out.println("import [horn]");
128         System.out.println("import [par2ser]");
129         System.out.println("import [ser2par]");
130
131         HashSet<Class> added = new HashSet<Class>();
132         for(Ship ship : shiplist)
133             if (!added.contains(ship.getClass())) {
134                 added.add(ship.getClass());
135                 System.out.println("import ["+ship.getBalsaName()+"]");
136             }
137
138         System.out.println("procedure fabric(input top_in:XBit; output top_out:XBit)");
139         System.out.println("is");
140         instructions.dumpChannels(true);
141         outputs.dumpChannels(true);
142         inputs.dumpChannels(true);
143         for(Ship ship : shiplist)
144             for(Port port : ship.portlist)
145                 System.out.println("  channel data_"+ship.getName()+"_"+port.getName()+" : XBit");
146         System.out.println("begin");
147         System.out.println("     loop source -> dest end");
148         System.out.println("  || loop top_in -> instruction end");
149         System.out.println("  || loop data_debug_out -> top_out end");
150         System.out.println("");
151         instructions.dumpChannels(false);
152         System.out.println("");
153         outputs.dumpChannels(false);
154         System.out.println("");
155         inputs.dumpChannels(false);
156         System.out.println("");
157         for(Ship ship : shiplist) {
158             System.out.print("  || ");
159             System.out.print(ship.getBalsaName());
160             System.out.print("(");
161             boolean first = true;
162             for(Port port : ship.portlist) {
163                 if (!first) System.out.print(", ");
164                 first = false;
165                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName());
166                 System.out.print(" ");
167             }
168             System.out.println(")");
169
170             for(Port port : ship.portlist) {
171                 if (ship instanceof DebugShip && port instanceof Outbox)
172                     continue;
173                 System.out.print("  || ");
174                 if (port instanceof Inbox)
175                     System.out.print("inbox(");
176                 else
177                     System.out.print("outbox(");
178                 System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName());
179                 System.out.print(", ");
180                 System.out.print("dest_"+port.getShip().getName()+"_"+port.getName());
181                 System.out.print(", ");
182                 System.out.print("source_"+port.getShip().getName()+"_"+port.getName());
183                 System.out.print(", ");
184                 System.out.print("data_"+port.getShip().getName()+"_"+port.getName());
185                 System.out.print(")");
186                 System.out.println();
187             }
188
189         }
190         System.out.println("end");
191     }
192
193     private static class FabricTree {
194         int master_idx = 1;
195         String prefix;
196         Node root;
197         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
198         public FabricTree(Port[] ports, String component, String prefix) {
199             this.prefix = prefix;
200             root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
201         }
202         private Object mkNode(String name, String component, Port[] ports, int start, int end, int addr, int bits) {
203             if (end-start == 0) return null;
204             if (end-start == 1) {
205                 Port p = ports[start];
206                 if (prefix.equals("instruction")) {
207                     p.instr_addr = addr;
208                     p.instr_bits = bits;
209                 } else {
210                     p.addr = addr;
211                     p.bits = bits;
212                 }
213                 return p;
214             }
215             int len = end-start;
216             return new Node(name,
217                             component,
218                             mkNode(name+"_0", component, ports, start, start+len/2, (addr<<1)|0, bits+1),
219                             mkNode(name+"_1", component, ports, start+len/2, end, (addr<<1)|1, bits+1),
220                             addr,
221                             bits);
222         }
223         private String describe(String prefix, Object o) {
224             if (o==null) return null;
225             if (o instanceof Port) {
226                 Port p = (Port)o;
227                 return prefix+"_"+p.getShip().getName()+"_"+p.getName();
228             }
229             if (o instanceof Node) {
230                 return ((Node)o).describe(prefix);
231             }
232             return null;
233         }
234         private class Node {
235             Object left;
236             Object right;
237             String name;
238             String component;
239         int addr;
240         int bits;
241             public Node(String name, String component, Object left, Object right, int addr, int bits) {
242                 this.left = left;
243                 this.right = right;
244                 this.name = name;
245                 this.component = component;
246                 this.addr = addr;
247                 this.bits = bits;
248             }
249             public void dumpChannels(int indentamount, boolean decl) {
250                 String indent = "";
251                 for(int i=0; i<indentamount; i++) indent += "  ";
252                 if (decl) {
253                     System.out.println("  channel "+indent+describe(prefix)+" : XBit");
254                 } else {
255                     System.out.println("  || "+indent+
256                                        component+"("+describe(prefix)+
257                                        ", "+FabricTree.this.describe(prefix, left)+
258                                        ", "+FabricTree.this.describe(prefix, right)+")");
259                 }
260                 dumpChannels(left, indentamount+1, decl);
261                 dumpChannels(right, indentamount+1, decl);
262             }
263             public void dumpChannels(Object o, int indentamount, boolean decl) {
264                 if (o==null) return;
265                 if (o instanceof Node) {
266                     ((Node)o).dumpChannels(indentamount, decl);
267                 } else {
268                     String indent = "";
269                     for(int i=0; i<indentamount; i++) indent += "  ";
270                     if (decl)
271                         System.out.println("  channel "+indent+FabricTree.this.describe(prefix,o)+" :XBit");
272                 }
273             }
274             public String describe(String prefix) {
275                 return prefix+name;
276             }
277         }
278     }
279
280 }