From b0c14940325a3204ba0a97822671f8c008ed8efe Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 23 Nov 2006 12:45:32 +0100 Subject: [PATCH] major refactoring, added token inboxes/outboxes --- fleet.g | 9 +- src/edu/berkeley/fleet/CodeBag.java | 1 + src/edu/berkeley/fleet/DataInbox.java | 24 +++++ src/edu/berkeley/fleet/DataOutbox.java | 21 ++++ src/edu/berkeley/fleet/Fleet.java | 10 ++ src/edu/berkeley/fleet/FleetParser.java | 49 +++++++-- src/edu/berkeley/fleet/Inbox.java | 114 +++++++++++++++++++++ src/edu/berkeley/fleet/InboxPort.java | 90 ---------------- src/edu/berkeley/fleet/Instruction.java | 4 +- src/edu/berkeley/fleet/InstructionPort.java | 55 +++++----- src/edu/berkeley/fleet/Literal.java | 5 +- src/edu/berkeley/fleet/Log.java | 29 +++--- src/edu/berkeley/fleet/Outbox.java | 85 +++++++++++++++ src/edu/berkeley/fleet/OutboxPort.java | 72 ------------- src/edu/berkeley/fleet/Port.java | 30 +++--- src/edu/berkeley/fleet/Ship.java | 7 +- src/edu/berkeley/fleet/TokenInPort.java | 31 ------ src/edu/berkeley/fleet/TokenInbox.java | 20 ++++ src/edu/berkeley/fleet/TokenOutPort.java | 59 ----------- src/edu/berkeley/fleet/TokenOutbox.java | 25 +++++ src/edu/berkeley/fleet/ships/BitBucketShip.java | 21 ++++ src/edu/berkeley/fleet/ships/DebugShip.java | 25 +++++ src/edu/berkeley/fleet/ships/FetchShip.java | 24 ++--- src/edu/berkeley/fleet/ships/FifoShip.java | 12 +-- src/edu/berkeley/fleet/ships/HaltShip.java | 6 +- src/edu/berkeley/fleet/ships/HomeworkCounter.java | 38 +++++++ src/edu/berkeley/fleet/ships/MemoryReadShip.java | 46 +++++++++ src/edu/berkeley/fleet/ships/TokenFifo.java | 30 ++++++ src/edu/berkeley/fleet/ships/TokenSourceShip.java | 6 +- 29 files changed, 595 insertions(+), 353 deletions(-) create mode 100644 src/edu/berkeley/fleet/DataInbox.java create mode 100644 src/edu/berkeley/fleet/DataOutbox.java create mode 100644 src/edu/berkeley/fleet/Inbox.java delete mode 100644 src/edu/berkeley/fleet/InboxPort.java create mode 100644 src/edu/berkeley/fleet/Outbox.java delete mode 100644 src/edu/berkeley/fleet/OutboxPort.java delete mode 100644 src/edu/berkeley/fleet/TokenInPort.java create mode 100644 src/edu/berkeley/fleet/TokenInbox.java delete mode 100644 src/edu/berkeley/fleet/TokenOutPort.java create mode 100644 src/edu/berkeley/fleet/TokenOutbox.java create mode 100644 src/edu/berkeley/fleet/ships/BitBucketShip.java create mode 100644 src/edu/berkeley/fleet/ships/DebugShip.java create mode 100644 src/edu/berkeley/fleet/ships/HomeworkCounter.java create mode 100644 src/edu/berkeley/fleet/ships/MemoryReadShip.java create mode 100644 src/edu/berkeley/fleet/ships/TokenFifo.java diff --git a/fleet.g b/fleet.g index 85ce537..4ef8ab6 100644 --- a/fleet.g +++ b/fleet.g @@ -20,10 +20,11 @@ Statement = Instruction:: (Opcode ws!)? Source ws! Arrow ws! Port Opcode = Triggered:: "triggered" OpcodeBody /ws | UnTriggered:: OpcodeBody -OpcodeBody = ^"nop" | ^"wait" | ^"discard" - | ^"nop+ack" | ^"wait+ack" | ^"discard+ack" - | ^"copy" | ^"move" | ^"accept" - | ^"copy+ack" | ^"move+ack" | ^"accept+ack" +OpcodeBody = ^"nop" | ^"wait" | ^"discard" + | ^"nop+ack" | ^"wait+ack" | ^"discard+ack" + | ^"copy" | ^"move" | ^"accept" + | ^"copy+ack" | ^"move+ack" | ^"accept+ack" + | ^"synthesize" | ^"synthesize+ack" Arrow = ^"->" | ^"-[*]->" diff --git a/src/edu/berkeley/fleet/CodeBag.java b/src/edu/berkeley/fleet/CodeBag.java index fc1a9af..64edd4b 100644 --- a/src/edu/berkeley/fleet/CodeBag.java +++ b/src/edu/berkeley/fleet/CodeBag.java @@ -2,6 +2,7 @@ package edu.berkeley.fleet; import java.util.*; +/** a codebag */ public class CodeBag { private static int max_allocated_descriptor = 1; diff --git a/src/edu/berkeley/fleet/DataInbox.java b/src/edu/berkeley/fleet/DataInbox.java new file mode 100644 index 0000000..b0afd28 --- /dev/null +++ b/src/edu/berkeley/fleet/DataInbox.java @@ -0,0 +1,24 @@ +package edu.berkeley.fleet; + +import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; +import java.util.*; + +public class DataInbox extends Inbox { + + public DataInbox(Ship ship, String name) { + super(ship, name); + } + + void addDataFromFabric(int data) { + addItemFromFabric(data); + } + + public boolean dataReadyForShip() { + return super.itemReadyForShip(); + } + + public int removeDataForShip() { + return super.accept(); + } + +} diff --git a/src/edu/berkeley/fleet/DataOutbox.java b/src/edu/berkeley/fleet/DataOutbox.java new file mode 100644 index 0000000..8e2f828 --- /dev/null +++ b/src/edu/berkeley/fleet/DataOutbox.java @@ -0,0 +1,21 @@ +package edu.berkeley.fleet; +import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; + +public class DataOutbox extends Outbox { + + public DataOutbox(Ship ship, String name) { + super(ship, name); + } + + public void addDataFromShip(int data) { + addItemFromShip(data); + } + + public boolean readyForDataFromShip() { + return super.readyForItemFromShip(); + } + + protected void send(Port port, int data) { + getFleet().sendData(this, data, port); + } +} diff --git a/src/edu/berkeley/fleet/Fleet.java b/src/edu/berkeley/fleet/Fleet.java index b1e2ac9..7a9cc9e 100644 --- a/src/edu/berkeley/fleet/Fleet.java +++ b/src/edu/berkeley/fleet/Fleet.java @@ -62,4 +62,14 @@ public class Fleet { return false; } } + + public void sendToken(Port source, Port dest) { + Log.token(source, dest); + dest.addTokenFromFabric(); + } + + public void sendData(Port source, int data, Port dest) { + Log.data(data+"", source, dest); + dest.addDataFromFabric(data); + } } diff --git a/src/edu/berkeley/fleet/FleetParser.java b/src/edu/berkeley/fleet/FleetParser.java index 7130f7e..85fc297 100644 --- a/src/edu/berkeley/fleet/FleetParser.java +++ b/src/edu/berkeley/fleet/FleetParser.java @@ -13,6 +13,33 @@ import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; public class FleetParser { public static void main(String[] s) throws Exception { + for(int i=0; i itemsFromFabric = new LinkedList(); + + /** a datum which has been presented to the ship */ + private int itemPresentedToShip; + + /** true iff data is currently being presented to the ship */ + private boolean itemReadyForShip = false; + + /** if an ack token is pending, this is where it should be sent once the item is accepted */ + private Port ackDestinationUponAccept; + + + // protected methods ///////////////////////////////////////////////////////////////////////// + + Inbox(Ship ship, String name) { + super(ship, name); + + // default standing move + if (defaultInstruction != null) + addInstruction(defaultInstruction); + } + + /** subclasses invoke this when items arrive from the fabric */ + protected final void addItemFromFabric(int data) { + itemsFromFabric.add(data); + } + + /** true iff data is ready for the ship to accept */ + protected final boolean itemReadyForShip() { + return itemReadyForShip; + } + + /** accpets (removes) an item -- invoked by the ship */ + protected final int accept() { + if (!itemReadyForShip) + throw new RuntimeException("invoked accept() on an inbox which does not have items ready; your ship is buggy"); + itemReadyForShip = false; + if (ackDestinationUponAccept != null) { + getFleet().sendToken(this, ackDestinationUponAccept); + ackDestinationUponAccept = null; + } + return itemPresentedToShip; + } + + /** invoked by superclass */ + protected final boolean service(Instruction instruction) { + + // if data is stuck on itemPresentedToShip, wait for it to go somewhere before + // considering additional instructions + if (itemReadyForShip) return false; + + // if no instruction waiting, do nothing + if (instruction == null) return false; + + // check firing conditions + if (instruction.trigger) + throw new RuntimeException("invalid instruction: " + instruction + + " (attempts to use trigger on an inbox)"); + if (instruction.dataIn != IGNORE && itemsFromFabric.size()==0) return false; + + // consume inbound data+token + switch(instruction.dataIn) { + case COPY: + itemPresentedToShip = itemsFromFabric.peek(); + break; + case TAKE: + itemPresentedToShip = itemsFromFabric.remove(); + break; + } + + // if dataOut, present data to the ship + if (instruction.dataOut) { + itemReadyForShip = true; + + // and make note of the fact that we need to send an ack (if requested) + if (instruction.ack) + ackDestinationUponAccept = instruction.destination.resolve(getShip().getFleet()); + + } else if (instruction.ack) { + + // if dataOut is not set, we can send the data immediately + getFleet().sendToken(this, instruction.destination.resolve(getShip().getFleet())); + } + return true; + } + + protected void shutdown() { + if (itemReadyForShip) + Log.println(Log.red(" WARNING: a datum ("+itemPresentedToShip+") was left in inbox " + + this + " -- the ship has not consumed it")); + + if (itemsFromFabric.size() > 0) { + Log.println(Log.red(" WARNING: you left data on the input to inbox " + this + ":")); + for(int i : itemsFromFabric) + Log.println(" " + i); + } + super.shutdown(true); + } +} diff --git a/src/edu/berkeley/fleet/InboxPort.java b/src/edu/berkeley/fleet/InboxPort.java deleted file mode 100644 index bae09b2..0000000 --- a/src/edu/berkeley/fleet/InboxPort.java +++ /dev/null @@ -1,90 +0,0 @@ -package edu.berkeley.fleet; - -import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; -import java.util.*; - -public class InboxPort extends InstructionPort { - - public static final Instruction defaultInstruction = - new Instruction(null, null, Integer.MAX_VALUE, TAKE, false, false, true); - - public InboxPort(Ship ship, String name) { - super(ship, name); - - // default standing move - addInstruction(defaultInstruction); - } - - // data in from the switch fabric - private Queue dataIn = new LinkedList(); - public void addData(int data) { dataIn.add(data); } - public void addToken() { throw new RuntimeException("inboxes do not accept tokens!"); } - - // data out to the ship - private boolean empty = true; - private int dataOut; - private Port tokenDestination; - - public boolean empty() { return empty; } - public int remove() { - if (empty) - throw new RuntimeException("called remove() on an empty() inbox"); - empty = true; - if (tokenDestination != null) { - Log.token(this, tokenDestination); - tokenDestination.addToken(); - tokenDestination = null; - } - return dataOut; - } - - public boolean service(Instruction instruction) { - - // if data is stuck on dataOut, wait for it to go somewhere - if (!empty) return false; - - // if no instruction waiting, do nothing - if (instruction == null) return false; - - // check firing conditions - if (instruction.trigger) - throw new RuntimeException("you cannot send a triggered instruction to an inbox!"); - if (instruction.dataIn != IGNORE && dataIn.size()==0) return false; - - // consume inbound data+token - int data = 0; - switch(instruction.dataIn) { - case COPY: - dataOut = dataIn.peek(); - break; - case TAKE: - dataOut = dataIn.remove(); - break; - - } - - if (instruction.dataOut) { - empty = false; - if (instruction.ack) - tokenDestination = instruction.destination.resolve(getShip().getFleet()); - - } else if (instruction.ack) { - Port p = instruction.destination.resolve(getShip().getFleet()); - Log.token(this, p); - p.addToken(); - } - return true; - } - - public void shutdown() { - if (!empty) - Log.println(Log.red(" WARNING: a datum ("+dataOut+") was left in inbox " + this + " -- the ship has not consumed it")); - - if (dataIn.size() > 0) { - Log.println(Log.red(" WARNING: you left data on the input to inbox " + this + ":")); - for(int i : dataIn) - Log.println(" " + i); - } - super.shutdown(true); - } -} diff --git a/src/edu/berkeley/fleet/Instruction.java b/src/edu/berkeley/fleet/Instruction.java index b4485f5..369c37e 100644 --- a/src/edu/berkeley/fleet/Instruction.java +++ b/src/edu/berkeley/fleet/Instruction.java @@ -1,6 +1,6 @@ package edu.berkeley.fleet; -/** an instruction within a codebag, as specified in am10 */ +/** an instruction within a codebag, as specified in am10; this class is immutable */ public class Instruction extends Dispatchable { public final PortReference source; @@ -43,7 +43,7 @@ public class Instruction extends Dispatchable { if (trigger) ret.append("triggered "); switch(dataIn) { case IGNORE: - ret.append("nop"); + ret.append(dataOut ? "synthesize" : "nop"); break; case COPY: ret.append(dataOut ? "copy" : "wait"); diff --git a/src/edu/berkeley/fleet/InstructionPort.java b/src/edu/berkeley/fleet/InstructionPort.java index 415ad1c..14638ce 100644 --- a/src/edu/berkeley/fleet/InstructionPort.java +++ b/src/edu/berkeley/fleet/InstructionPort.java @@ -2,15 +2,24 @@ package edu.berkeley.fleet; import java.util.*; -/** common superclass for any port which can take an instruction: inbox/outbox/tokenoutbox */ +/** anything that has a source (instruction horn) address on the switch fabric */ public abstract class InstructionPort extends Port { - public InstructionPort(Ship ship, String name) { + /** the currently executing instruction */ + Instruction currentlyExecuting = null; + + /** all instructions waiting to be executed (excludes currentlyExecuting) */ + Queue instructions = new LinkedList(); + + /** the count field of currentlyExecuting, taking into account actions already performed */ + int currentlyExecutingCount; + + InstructionPort(Ship ship, String name) { super(ship, name); } - /** add an instruction to the box */ - public void addInstruction(Instruction instr) { + /** an instruction arrives from the instruction horn */ + void addInstruction(Instruction instr) { if (currentlyExecuting != null && currentlyExecuting.count == Integer.MAX_VALUE) { currentlyExecuting = null; currentlyExecutingCount = 0; @@ -23,35 +32,27 @@ public abstract class InstructionPort extends Port { } } - // inherited from Port - public abstract void addData(int data); - - Instruction currentlyExecuting = null; - Queue instructions = new LinkedList(); - int currentlyExecutingCount; - - protected void shutdown(boolean leaveAsInbox) { - if (leaveAsInbox) { + if (leaveAsInbox && DataInbox.defaultInstruction != null) { if (currentlyExecuting == null) { Log.println(Log.red(" WARNING: you did not leave a standing move on inbox-port " + this)); return; - } else { - if (currentlyExecuting.count != Integer.MAX_VALUE - || currentlyExecuting.dataIn != Instruction.IgnoreCopyTake.TAKE - || currentlyExecuting.ack - || currentlyExecuting.trigger - || !currentlyExecuting.dataOut) { - Log.println(Log.red(" WARNING: you did not leave the correct standing move on inbox-port " + this)+ - "\n found: " + currentlyExecuting - ); - return; - } + } + if (currentlyExecuting.count != Integer.MAX_VALUE + || currentlyExecuting.dataIn != Instruction.IgnoreCopyTake.TAKE + || currentlyExecuting.ack + || currentlyExecuting.trigger + || !currentlyExecuting.dataOut) { + Log.println(Log.red(" WARNING: you did not leave the correct standing move on inbox-port " + this)+ + "\n found: " + currentlyExecuting + ); + return; } currentlyExecuting = null; } if (currentlyExecuting != null || instructions.size() > 0) { - Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " + this + "; they are:")); + Log.println(Log.red(" WARNING: you left instructions on the instruction queue of port " + + this + "; they are:")); if (currentlyExecuting != null) Log.println(" " + currentlyExecuting); for(Instruction i : instructions) @@ -61,10 +62,10 @@ public abstract class InstructionPort extends Port { // interface to subclass /////////////////////////////////////////////////////////////////////// - /** this will be invoked periodically; should return true to "consume" an instruction */ + /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */ protected abstract boolean service(Instruction instr); - public void service() { + protected final void service() { if (currentlyExecutingCount <= 0) currentlyExecuting = null; if (currentlyExecuting == null && instructions.size() > 0) { diff --git a/src/edu/berkeley/fleet/Literal.java b/src/edu/berkeley/fleet/Literal.java index e9e9a9c..a4c0b77 100644 --- a/src/edu/berkeley/fleet/Literal.java +++ b/src/edu/berkeley/fleet/Literal.java @@ -1,5 +1,6 @@ package edu.berkeley.fleet; +/** represents a literal; currently handled in an extremely hoakey fashion */ public class Literal { public static class LiteralDatum extends Dispatchable { @@ -19,7 +20,7 @@ public class Literal { for(int i=0; i "+destination; diff --git a/src/edu/berkeley/fleet/Log.java b/src/edu/berkeley/fleet/Log.java index 0deb246..fec2893 100644 --- a/src/edu/berkeley/fleet/Log.java +++ b/src/edu/berkeley/fleet/Log.java @@ -3,6 +3,8 @@ import java.io.*; public class Log { + public static boolean ansi_color = true; + public static PrintWriter log = new PrintWriter(new OutputStreamWriter(System.out)); public static void print(Object o) { @@ -34,24 +36,17 @@ public class Log { println(purple(" token: ") + (source + " -> " + purple(dest+""))); } - //public static String black(Object o) { return "\033[30m"+o+"\033[0m"; } - public static String black(Object o) { return o+""; } - //public static String clreol() { return "\033[0K"; } public static String clreol() { return ""; } - public static String red(Object o) { return "\033[31m"+o+"\033[0m"; } - //public static String red(Object o) { return o+""; } - public static String green(Object o) { return "\033[32m"+o+"\033[0m"; } - //public static String green(Object o) { return o+""; } - public static String yellow(Object o) { return "\033[33m"+o+"\033[0m"; } - //public static String yellow(Object o) { return o+""; } - //public static String blue(Object o) { return "\033[34m"+o+"\033[0m"; } - public static String blue(Object o) { return o+""; } - public static String purple(Object o) { return "\033[35m"+o+"\033[0m"; } - //public static String purple(Object o) { return o+""; } - public static String cyan(Object o) { return "\033[36m"+o+"\033[0m"; } - //public static String cyan(Object o) { return o+""; } - public static String invert(Object o) { return "\033[7m"+o+"\033[0m"; } - public static String bold(Object o) { return "\033[1m"+o+"\033[0m"; } + + public static String black(Object o) { if (!ansi_color) return o+""; return o+""; } + public static String red(Object o) { if (!ansi_color) return o+""; return "\033[31m"+o+"\033[0m"; } + public static String green(Object o) { if (!ansi_color) return o+""; return "\033[32m"+o+"\033[0m"; } + public static String yellow(Object o) { if (!ansi_color) return o+""; return "\033[33m"+o+"\033[0m"; } + public static String blue(Object o) { if (!ansi_color) return o+""; return o+""; } + public static String purple(Object o) { if (!ansi_color) return o+""; return "\033[35m"+o+"\033[0m"; } + public static String cyan(Object o) { if (!ansi_color) return o+""; return "\033[36m"+o+"\033[0m"; } + public static String invert(Object o) { if (!ansi_color) return o+""; return "\033[7m"+o+"\033[0m"; } + public static String bold(Object o) { if (!ansi_color) return o+""; return "\033[1m"+o+"\033[0m"; } public static String indent(String s, String indent) { StringBuffer ret = new StringBuffer(); diff --git a/src/edu/berkeley/fleet/Outbox.java b/src/edu/berkeley/fleet/Outbox.java new file mode 100644 index 0000000..ba089bb --- /dev/null +++ b/src/edu/berkeley/fleet/Outbox.java @@ -0,0 +1,85 @@ +package edu.berkeley.fleet; +import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; + +public abstract class Outbox extends InstructionPort { + + /** are we ready to accept another item from the ship? */ + private boolean readyForItemFromShip = true; + + /** data which has been presented by the ship and is waiting to depart */ + private int itemPresentedByShip; + + /** number of tokens queued on the trigger input */ + private int triggersReceived = 0; + + protected Outbox(Ship ship, String name) { + super(ship, name); + } + + protected final boolean readyForItemFromShip() { + return readyForItemFromShip; + } + + final void addTokenFromFabric() { + triggersReceived++; + } + + protected final boolean service(Instruction instruction) { + + // if no instruction waiting, do nothing + if (instruction == null) return false; + + // check firing conditions + if (instruction.trigger && triggersReceived <= 0) return false; + if (instruction.dataIn != IGNORE && readyForItemFromShip) return false; + + // consume trigger + if (instruction.trigger) triggersReceived--; + + // consume item + int data = 0; + switch(instruction.dataIn) { + case COPY: + data = itemPresentedByShip; + break; + case TAKE: + data = itemPresentedByShip; + readyForItemFromShip = true; + break; + } + + if (instruction.dataOut) { + + // if item to be transmitted, send it + send(instruction.destination.resolve(getShip().getFleet()), data); + if (instruction.ack) + throw new RuntimeException("outboxes may not send acks!"); + + } else if (instruction.ack) { + + // if no item was sent, we might still send an ack + getFleet().sendToken(this, instruction.destination.resolve(getShip().getFleet())); + } + + return true; + } + + /** this is invoked to transmit data; the subclass decides if it is a token or not */ + protected abstract void send(Port port, int data); + + /** subclass invokes this to add an item from the ship */ + protected final void addItemFromShip(int data) { + if (!readyForItemFromShip) + throw new RuntimeException("tried to add an item to an outbox which was not ready! you have a buggy ship!"); + readyForItemFromShip = false; + itemPresentedByShip = data; + } + + void shutdown() { + if (!readyForItemFromShip) + Log.println(Log.red(" WARNING: you left a value ("+itemPresentedByShip+") on outbox port " + this)); + if (triggersReceived > 0) + Log.println(Log.red(" WARNING: you left a token on the trigger input to port " + this)); + super.shutdown(false); + } +} diff --git a/src/edu/berkeley/fleet/OutboxPort.java b/src/edu/berkeley/fleet/OutboxPort.java deleted file mode 100644 index b79a74f..0000000 --- a/src/edu/berkeley/fleet/OutboxPort.java +++ /dev/null @@ -1,72 +0,0 @@ -package edu.berkeley.fleet; -import static edu.berkeley.fleet.Instruction.IgnoreCopyTake.*; - -public class OutboxPort extends InstructionPort { - - public OutboxPort(Ship ship, String name) { - super(ship, name); - } - - // data in from the ship - private boolean empty = true; - private int dataIn; - - public boolean empty() { return empty; } - - /** number of tokens queued on the trigger input */ - private int trigger = 0; - public void addToken() { trigger++; } - - public void addData(int data) { - if (!empty) - throw new RuntimeException("tried to add data to a non-empty outbox! you have a buggy ship!"); - empty = false; - dataIn = data; - } - - public boolean service(Instruction instruction) { - - // if no instruction waiting, do nothing - if (instruction == null) return false; - - // check firing conditions - if (instruction.trigger && trigger <= 0) return false; - if (instruction.dataIn != IGNORE && empty) return false; - - // consume inbound data+token - if (instruction.trigger) trigger--; - int data = 0; - switch(instruction.dataIn) { - case COPY: - data = dataIn; - break; - case TAKE: - data = dataIn; - empty = true; - break; - } - - if (instruction.dataOut) { - Port port = instruction.destination.resolve(getShip().getFleet()); - Log.data(data+"", this, port); - port.addData(data); - if (instruction.ack) - throw new RuntimeException("outboxes may not send acks!"); - - } else if (instruction.ack) { - Port p = instruction.destination.resolve(getShip().getFleet()); - Log.token(this, p); - p.addToken(); - } - - return true; - } - - public void shutdown() { - if (!empty) - Log.println(Log.red(" WARNING: you left a value ("+dataIn+") on outbox port " + this)); - if (trigger > 0) - Log.println(Log.red(" WARNING: you left a token on the trigger input to port " + this)); - super.shutdown(false); - } -} diff --git a/src/edu/berkeley/fleet/Port.java b/src/edu/berkeley/fleet/Port.java index ca049b0..0d865cb 100644 --- a/src/edu/berkeley/fleet/Port.java +++ b/src/edu/berkeley/fleet/Port.java @@ -1,10 +1,10 @@ package edu.berkeley.fleet; -/** a destination on the switch fabric */ +/** anything that has a destination address on the switch fabric */ public abstract class Port { - public final String name; - public final Ship ship; + private final String name; + private final Ship ship; public Port(Ship ship, String name) { this.ship = ship; @@ -12,19 +12,25 @@ public abstract class Port { ship.addPort(name, this); } - public void service() { } + void service() { } - /** adds one token to the port */ - public abstract void addToken(); + /** adds one token to the port from the switch fabric side */ + void addTokenFromFabric() { throw new RuntimeException("this should never happen!"); } - /** adds the included datum to the port */ - public abstract void addData(int datum); + /** adds the included datum to the port from the switch fabric side */ + void addDataFromFabric(int datum) { throw new RuntimeException("this should never happen!"); } - public Ship getShip() { - return ship; - } + /** adds one token to the port from the ship side */ + public void addTokenFromShip() { throw new RuntimeException("this should never happen!"); } + + /** adds the included datum to the port from the switch fabric side */ + public void addDataFromShip(int datum) { throw new RuntimeException("this should never happen!"); } + + public Ship getShip() { return ship; } + + public Fleet getFleet() { return getShip().getFleet(); } public String toString() { return ship+"."+name; } - public abstract void shutdown(); + abstract void shutdown(); } diff --git a/src/edu/berkeley/fleet/Ship.java b/src/edu/berkeley/fleet/Ship.java index 8eb93b4..c85d7d0 100644 --- a/src/edu/berkeley/fleet/Ship.java +++ b/src/edu/berkeley/fleet/Ship.java @@ -8,12 +8,13 @@ import edu.berkeley.sbp.util.*; import java.util.*; import java.io.*; +/** a ship, which belongs to a fleet and which may have many ports */ public abstract class Ship { - HashMap ports = new HashMap(); + private HashMap ports = new HashMap(); private String name; - protected Fleet fleet; + private Fleet fleet; /** You should instantiate a bunch of Inboxes and Outboxes in your constructor */ public Ship(Fleet fleet, String name) { @@ -44,7 +45,7 @@ public abstract class Ship { service(); } - public void addPort(String name, Port port) { + void addPort(String name, Port port) { ports.put(name, port); } diff --git a/src/edu/berkeley/fleet/TokenInPort.java b/src/edu/berkeley/fleet/TokenInPort.java deleted file mode 100644 index 990ba89..0000000 --- a/src/edu/berkeley/fleet/TokenInPort.java +++ /dev/null @@ -1,31 +0,0 @@ -package edu.berkeley.fleet; - -public class TokenInPort extends Port { - - private int tokens = 0; - - public TokenInPort(Ship ship, String name) { - super(ship, name); - } - - public void addToken() { - tokens++; - } - - public void addData(int data) { - throw new RuntimeException("invalid!"); - } - - public boolean empty() { - return tokens==0; - } - - public void remove() { - tokens--; - } - - public void shutdown() { - if (tokens > 0) - Log.println(Log.red(" WARNING: tokens were left on the input to " + this)); - } -} diff --git a/src/edu/berkeley/fleet/TokenInbox.java b/src/edu/berkeley/fleet/TokenInbox.java new file mode 100644 index 0000000..c18d690 --- /dev/null +++ b/src/edu/berkeley/fleet/TokenInbox.java @@ -0,0 +1,20 @@ +package edu.berkeley.fleet; + +public class TokenInbox extends Inbox { + + public TokenInbox(Ship ship, String name) { + super(ship, name); + } + + void addTokenFromFabric() { + addItemFromFabric(0); + } + + public boolean tokenReadyForShip() { + return super.itemReadyForShip(); + } + + public void removeTokenForShip() { + super.accept(); + } +} diff --git a/src/edu/berkeley/fleet/TokenOutPort.java b/src/edu/berkeley/fleet/TokenOutPort.java deleted file mode 100644 index 790cc0f..0000000 --- a/src/edu/berkeley/fleet/TokenOutPort.java +++ /dev/null @@ -1,59 +0,0 @@ -package edu.berkeley.fleet; - -/** a port which outputs only tokens */ -public class TokenOutPort extends InstructionPort { - - private boolean empty = true; - - public TokenOutPort(Ship ship, String name) { - super(ship, name); - } - - public boolean empty() { - return empty; - } - - public void addToken() { - if (!empty) - throw new RuntimeException("tried to add data to a non-empty tokenoutbox! you have a buggy ship!"); - empty = false; - } - - public boolean service(Instruction instruction) { - - // if no instruction waiting, do nothing - if (instruction == null) return false; - - // check firing conditions - if (instruction.trigger) - throw new RuntimeException("you cannot send triggered instructions to token-output ports"); - - switch(instruction.dataIn) { - case COPY: - if (empty) return false; - break; - case TAKE: - if (empty) return false; - empty = true; - break; - case IGNORE: - if (!instruction.ack) return true; - // fall through - } - - Port port = instruction.destination.resolve(getShip().getFleet()); - Log.token(this, port); - port.addToken(); - return true; - } - - public void addData(int data) { - throw new RuntimeException("invalid!"); - } - - public void shutdown() { - if (!empty) - Log.println(Log.red(" WARNING: you left a token on token-output port " + this)); - super.shutdown(false); - } -} diff --git a/src/edu/berkeley/fleet/TokenOutbox.java b/src/edu/berkeley/fleet/TokenOutbox.java new file mode 100644 index 0000000..d690c23 --- /dev/null +++ b/src/edu/berkeley/fleet/TokenOutbox.java @@ -0,0 +1,25 @@ +package edu.berkeley.fleet; + +/** a port which outputs only tokens */ +public class TokenOutbox extends Outbox { + + public TokenOutbox(Ship ship, String name) { + super(ship, name); + } + + protected void send(Port port, int data) { + getFleet().sendToken(this, port); + } + + public boolean readyForDataFromShip() { + return super.readyForItemFromShip(); + } + + public void addTokenFromShip() { + addItemFromShip(0); + } + + public boolean readyForToken() { + return readyForDataFromShip(); + } +} diff --git a/src/edu/berkeley/fleet/ships/BitBucketShip.java b/src/edu/berkeley/fleet/ships/BitBucketShip.java new file mode 100644 index 0000000..36e61e3 --- /dev/null +++ b/src/edu/berkeley/fleet/ships/BitBucketShip.java @@ -0,0 +1,21 @@ +package edu.berkeley.fleet.ships; +import edu.berkeley.fleet.*; + +import java.util.*; +import java.io.*; + +public class BitBucketShip extends Ship { + + TokenInbox token = new TokenInbox(this, "token"); + DataInbox data = new DataInbox(this, "data"); + + public BitBucketShip(Fleet fleet, String name) { + super(fleet, name); + } + + public void service() { + if (token.tokenReadyForShip()) token.removeTokenForShip(); + if (data.dataReadyForShip()) data.removeDataForShip(); + } + +} diff --git a/src/edu/berkeley/fleet/ships/DebugShip.java b/src/edu/berkeley/fleet/ships/DebugShip.java new file mode 100644 index 0000000..dc14450 --- /dev/null +++ b/src/edu/berkeley/fleet/ships/DebugShip.java @@ -0,0 +1,25 @@ +package edu.berkeley.fleet.ships; +import edu.berkeley.fleet.*; + +import java.util.*; +import java.io.*; + +public class DebugShip extends Ship { + + TokenInbox token = new TokenInbox(this, "token"); + DataInbox data = new DataInbox(this, "data"); + + public DebugShip(Fleet fleet, String name) { + super(fleet, name); + } + + public void service() { + if (token.tokenReadyForShip()) { + Log.println(Log.invert(" DEBUG: got a token"+Log.clreol())); + token.removeTokenForShip(); + } + if (data.dataReadyForShip()) + Log.println(Log.invert(" DEBUG: got a datum: " + data.removeDataForShip()+Log.clreol())); + } + +} diff --git a/src/edu/berkeley/fleet/ships/FetchShip.java b/src/edu/berkeley/fleet/ships/FetchShip.java index 2aa9f37..080f1a7 100644 --- a/src/edu/berkeley/fleet/ships/FetchShip.java +++ b/src/edu/berkeley/fleet/ships/FetchShip.java @@ -6,33 +6,33 @@ import java.io.*; public class FetchShip extends Ship { - InboxPort codebag = new InboxPort(this, "codebag"); - TokenInPort release = new TokenInPort(this, "release"); - TokenInPort revoke = new TokenInPort(this, "revoke"); - TokenOutPort done = new TokenOutPort(this, "done"); + DataInbox codebag = new DataInbox(this, "codebag"); + TokenInbox release = new TokenInbox(this, "release"); + TokenInbox revoke = new TokenInbox(this, "revoke"); + TokenOutbox done = new TokenOutbox(this, "done"); public FetchShip(Fleet fleet, String name) { super(fleet, name); } public void service() { - if (codebag.empty()) return; - if (release.empty() && revoke.empty()) return; - if (!done.empty()) return; - int cbd = codebag.remove(); + if (!codebag.dataReadyForShip()) return; + if (!release.tokenReadyForShip() && !revoke.tokenReadyForShip()) return; + if (!done.readyForToken()) return; + int cbd = codebag.removeDataForShip(); CodeBag cb = CodeBag.getCodeBagByDescriptor(cbd); - if (!revoke.empty()) { - revoke.remove(); + if (revoke.tokenReadyForShip()) { + revoke.removeTokenForShip(); Log.print("revoking codebag: " + cb); } else { - release.remove(); + release.removeTokenForShip(); if (cb==null) throw new RuntimeException("bogus codebag -- this should not happen"); cb.dispatch(getFleet()); } - done.addToken(); + done.addTokenFromShip(); } } diff --git a/src/edu/berkeley/fleet/ships/FifoShip.java b/src/edu/berkeley/fleet/ships/FifoShip.java index 8cff71c..44195e9 100644 --- a/src/edu/berkeley/fleet/ships/FifoShip.java +++ b/src/edu/berkeley/fleet/ships/FifoShip.java @@ -6,8 +6,8 @@ import java.io.*; public class FifoShip extends Ship { - InboxPort in = new InboxPort(this, "in"); - OutboxPort out = new OutboxPort(this, "out"); + DataInbox in = new DataInbox(this, "in"); + DataOutbox out = new DataOutbox(this, "out"); private Queue fifo = new LinkedList(); @@ -16,12 +16,12 @@ public class FifoShip extends Ship { } public void service() { - if (!in.empty()) { - fifo.add(in.remove()); + if (in.dataReadyForShip()) { + fifo.add(in.removeDataForShip()); //Log.println(name + ": fifo occupancy is now " + fifo.size() + " items"); } - if (out.empty() && fifo.size() > 0) { - out.addData(fifo.remove()); + if (out.readyForDataFromShip() && fifo.size() > 0) { + out.addDataFromShip(fifo.remove()); //Log.println(name + ": fifo occupancy is now " + fifo.size() + " items"); } } diff --git a/src/edu/berkeley/fleet/ships/HaltShip.java b/src/edu/berkeley/fleet/ships/HaltShip.java index 3cd7746..d10e43f 100644 --- a/src/edu/berkeley/fleet/ships/HaltShip.java +++ b/src/edu/berkeley/fleet/ships/HaltShip.java @@ -6,15 +6,15 @@ import java.io.*; public class HaltShip extends Ship { - TokenInPort in = new TokenInPort(this, "in"); + TokenInbox in = new TokenInbox(this, "in"); public HaltShip(Fleet fleet, String name) { super(fleet, name); } public void service() { - if (in.empty()) return; - in.remove(); + if (!in.tokenReadyForShip()) return; + in.removeTokenForShip(); getFleet().halt = true; Log.println(Log.yellow(" HALT: ====== halt ship got a token; halting the fleet ======")); } diff --git a/src/edu/berkeley/fleet/ships/HomeworkCounter.java b/src/edu/berkeley/fleet/ships/HomeworkCounter.java new file mode 100644 index 0000000..ee265ec --- /dev/null +++ b/src/edu/berkeley/fleet/ships/HomeworkCounter.java @@ -0,0 +1,38 @@ +package edu.berkeley.fleet.ships; +import edu.berkeley.fleet.*; + +import java.util.*; +import java.io.*; + +public class HomeworkCounter extends Ship { + + private int count = -1; + + TokenOutbox zero = new TokenOutbox(this, "zero"); + TokenOutbox positive = new TokenOutbox(this, "positive"); + DataInbox load = new DataInbox(this, "load"); + TokenInbox ask = new TokenInbox(this, "ask"); + + public HomeworkCounter(Fleet fleet, String name) { + super(fleet, name); + } + + public void service() { + if (!zero.readyForToken()) return; + if (!positive.readyForToken()) return; + if (load.dataReadyForShip()) { + count = load.removeDataForShip(); + return; + } + if (ask.tokenReadyForShip()) { + ask.removeTokenForShip(); + if (count > 0) { + count--; + positive.addTokenFromShip(); + } else if (count<=0) { + zero.addTokenFromShip(); + } + } + } + +} diff --git a/src/edu/berkeley/fleet/ships/MemoryReadShip.java b/src/edu/berkeley/fleet/ships/MemoryReadShip.java new file mode 100644 index 0000000..515351a --- /dev/null +++ b/src/edu/berkeley/fleet/ships/MemoryReadShip.java @@ -0,0 +1,46 @@ +package edu.berkeley.fleet.ships; + +import edu.berkeley.fleet.*; +import java.util.*; +import java.io.*; + +public class MemoryReadShip extends Ship { + + boolean _loaded = false; + int _count = 0; + int _stride = 0; + int _addr = 0; + + DataInbox addr = new DataInbox(this, "addr"); + DataInbox stride = new DataInbox(this, "stride"); + DataInbox count = new DataInbox(this, "count"); + DataOutbox data = new DataOutbox(this, "data"); + TokenOutbox done = new TokenOutbox(this, "done"); + + public MemoryReadShip(Fleet fleet, String name) { + super(fleet, name); + } + + public void service() { + if (_count > 0) { + if (!data.readyForDataFromShip()) return; + data.addDataFromShip(_addr>=fleet.mem.length ? 0 : fleet.mem[_addr]); + _count--; + _addr += _stride; + if (_count==0) + done.addTokenFromShip(); + } else { + if (count.dataReadyForShip() && + addr.dataReadyForShip() && + stride.dataReadyForShip() && + done.readyForToken() && + data.readyForDataFromShip()) { + + _count = count.removeDataForShip(); + _addr = addr.removeDataForShip(); + _stride = stride.removeDataForShip(); + } + } + } + +} diff --git a/src/edu/berkeley/fleet/ships/TokenFifo.java b/src/edu/berkeley/fleet/ships/TokenFifo.java new file mode 100644 index 0000000..6ab4a86 --- /dev/null +++ b/src/edu/berkeley/fleet/ships/TokenFifo.java @@ -0,0 +1,30 @@ +package edu.berkeley.fleet.ships; +import edu.berkeley.fleet.*; + +import java.util.*; +import java.io.*; + +public class TokenFifo extends Ship { + + private int count = 0; + + TokenOutbox out = new TokenOutbox(this, "out"); + TokenInbox in = new TokenInbox(this, "in"); + + public TokenFifo(Fleet fleet, String name) { + super(fleet, name); + } + + public void service() { + if (in.tokenReadyForShip()) { + count++; + in.removeTokenForShip(); + return; + } + if (count > 0 && out.readyForToken()) { + count--; + out.addTokenFromShip(); + } + } + +} diff --git a/src/edu/berkeley/fleet/ships/TokenSourceShip.java b/src/edu/berkeley/fleet/ships/TokenSourceShip.java index bd59010..8de78b2 100644 --- a/src/edu/berkeley/fleet/ships/TokenSourceShip.java +++ b/src/edu/berkeley/fleet/ships/TokenSourceShip.java @@ -6,15 +6,15 @@ import java.io.*; public class TokenSourceShip extends Ship { - TokenOutPort out = new TokenOutPort(this, "out"); + TokenOutbox out = new TokenOutbox(this, "out"); public TokenSourceShip(Fleet fleet, String name) { super(fleet, name); } public void service() { - if (out.empty()) - out.addToken(); + if (out.readyForToken()) + out.addTokenFromShip(); } public void shutdown() { -- 1.7.10.4