+
+ // Reset //////////////////////////////////////////////////////////////////////////////
+
+ int doReset(Context ctx,
+ int phase,
+ Dock dock,
+ Port peer,
+ Destination ackDestination,
+ HashSet<Dock> sendTorpedoesTo,
+ boolean peerUsed) {
+ int ret = 0;
+ if (dock.getShip().getType().equals("Debug")) return ret;
+
+ switch(phase) {
+
+ // Phase 0: torpedo every output dock, put it in
+ // collecting mode. Cannot combine with phase 1,
+ // because until output docks are in vacuum mode we
+ // cannot be sure that the tokens to the input docks
+ // will eventually succeed. This may cause the
+ // instructions sent after the tokens to back up into
+ // the switch fabric.
+ case 0: {
+ if (!dock.isInputDock()) {
+ sendTorpedoesTo.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all output docks to confirm that they've been torpedoed]
+ // Phase 1: torpedo every input dock (causing them to flush), put it in loopback mode
+ case 1: {
+ if (dock.isInputDock()) {
+ sendTorpedoesTo.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+
+ // FIXME: this won't work right for ports that
+ // get "shared" by two senders (for example,
+ // inAddrRead1/2)
+
+ if (peerUsed && peer!=null) {
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ ((OutPort)peer).recvWord(lf);
+ ((OutPort)peer).sendToken(lf);
+ }
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all input docks to confirm that they've been torpedoed and have flushed]
+ // Phase 2: torpedo every output dock, have it absorb tokens
+ case 2: {
+ if (!dock.isInputDock()) {
+ sendTorpedoesTo.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ if (peer != null)
+ for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
+ lf.recvToken();
+ lf.sendToken(ackDestination);
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all output docks to confirm that they've absorbed enough tokens]
+ // Phase 3: torpedo every input dock, await confirmation, and we're done
+ case 3: {
+ if (dock.isInputDock()) {
+ if (peerUsed && peer!=null) {
+ sendTorpedoesTo.add(dock);
+ }
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ ret++;
+ }
+ break;
+ }
+ }
+ return ret;
+ }
+