/** * Returns <code>null</code> as a Tree EditPart holds no children under it. * * @return <code>null</code> */ protected List getModelChildren() { NamedObj namedObjectModel = getNamedObjectModel(); List children = new ArrayList(); if (namedObjectModel instanceof AtomicActor) { AtomicActor actor = (AtomicActor) namedObjectModel; children.addAll(actor.attributeList(Parameter.class)); children.addAll(actor.inputPortList()); children.addAll(actor.outputPortList()); } else if (namedObjectModel instanceof CompositeActor) { CompositeActor composite = (CompositeActor) namedObjectModel; children.addAll(composite.attributeList(AtomicActor.class)); children.addAll(composite.attributeList(Parameter.class)); children.addAll(composite.inputPortList()); Enumeration enumeration = composite.getEntities(); while (enumeration.hasMoreElements()) { children.add(enumeration.nextElement()); } } else if (namedObjectModel instanceof IOPort) { IOPort text = (IOPort) namedObjectModel; children.addAll(text.attributeList(ptolemy.kernel.util.StringAttribute.class)); } else if (namedObjectModel instanceof Vertex) { Vertex text = (Vertex) namedObjectModel; children.addAll(text.attributeList(Vertex.class)); } else if (namedObjectModel instanceof TextAttribute) { TextAttribute text = (TextAttribute) namedObjectModel; children.addAll(text.attributeList(ptolemy.kernel.util.StringAttribute.class)); } else if (namedObjectModel instanceof Director) { Director director = (Director) namedObjectModel; children.addAll(director.attributeList(Parameter.class)); } return children; }
/** * Read one RecordToken from the input port and send its fields to the output ports. If the input * does not have a token, suspend firing and return. * * @exception IllegalActionException If there is no director. */ public void fire() throws IllegalActionException { super.fire(); Director director = getDirector(); if (director == null) { throw new IllegalActionException(this, "No director!"); } if (input.hasToken(0)) { RecordToken record = (RecordToken) input.get(0); Iterator labels = record.labelSet().iterator(); while (labels.hasNext()) { String label = (String) labels.next(); Token value = record.get(label); IOPort port = (IOPort) getPort(label); // since the record received may contain more fields than the // output ports, some fields may not have a corresponding // output port. if (port != null) { port.send(0, value); } } } }
/** Refreshes the visual properties of the TreeItem for this part. */ protected void refreshVisuals() { if (getWidget() instanceof Tree) return; NamedObj model = getNamedObjectModel(); // Set Image if (model instanceof Director) setWidgetImage(DirectorEditPart.IMAGE_DESCRIPTOR_DIRECTOR, model); else if (model instanceof Parameter) setWidgetImage(ActorEditPart.IMAGE_DESCRIPTOR_PARAMETER, model); else if (model instanceof IOPort) { IOPort port = (IOPort) model; if (port.isInput()) setWidgetImage(ActorEditPart.IMAGE_DESCRIPTOR_INPUTPORT, model); else setWidgetImage(ActorEditPart.IMAGE_DESCRIPTOR_OUTPUTPORT, model); } else if (model instanceof TypedAtomicActor) { setWidgetImage(ActorEditPart.IMAGE_DESCRIPTOR_ACTOR, model); } else if (model instanceof CompositeActor) { setWidgetImage(PaletteBuilder.getInstance().getIcon(model.getClass()), model); } // Set Text if (model instanceof Parameter) { Parameter param = (Parameter) model; String name = param.getName(); String value = param.getExpression(); setWidgetText(name + "=" + (value == null ? "" : value)); } else setWidgetText(model.getName()); }
/** @return the model entities (should be actors) that can still send input msgs to this port */ public synchronized Set<Entity> getActiveSources() { Set<Entity> results = new HashSet<Entity>(); for (IOPort port : operationalSourcePorts) { results.add((Entity) port.getContainer()); } return results; }
/** * Return a list of source ports connected to this port on the same layer that can send data to * this port. This includes output ports that are connected on the outside to this port, and input * ports that are connected on the inside to this port. * * @param input TypedIOPort * @return A list of IOPort objects. */ private LinkedList _shallowSourcePortList(TypedIOPort input) { try { _workspace.getReadAccess(); Actor container = (Actor) input.getContainer(); Director excDirector = ((Actor) container).getExecutiveDirector(); int depthOfContainer = ((NamedObj) container).depthInHierarchy(); LinkedList result = new LinkedList(); Iterator ports = input.connectedPortList().iterator(); while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); int depth = port.depthInHierarchy(); if (port.isInput() && (depth <= depthOfContainer)) { result.addLast(port); } else if (port.isOutput() && (depth == (depthOfContainer + 1))) { result.addLast(port); } } return result; } finally { _workspace.doneReading(); } }
/** * Set the container. This overrides the base class to record the director. * * @param port The container. * @exception IllegalActionException If the container is not of an appropriate subclass of IOPort, * or if the container's director is not an instance of PNDirector. */ public void setContainer(IOPort port) throws IllegalActionException { super.setContainer(port); if (port == null) { _director = null; } else { Actor actor = (Actor) port.getContainer(); Director director; // For a composite actor, // the receiver type of an input port is decided by // the executive director. // While the receiver type of an output is decided by the director. // NOTE: getExecutiveDirector() and getDirector() yield the same // result for actors that do not contain directors. if (port.isInput()) { director = actor.getExecutiveDirector(); } else { director = actor.getDirector(); } if (!(director instanceof PNDirector)) { throw new IllegalActionException( port, "Cannot use an instance of PNQueueReceiver " + "since the director is not a PNDirector."); } _director = (PNDirector) director; } }
/** * Create a map containing the services and Receivers ID's corresponding to a given bidimensional * array of Receiver. i.e. ((service1, (ID1, ..., IDi), ..., (servicen, (IDj, ..., IDr)). * * @param receivers The bidimensional array of Receivers. * @return A HashMap containing services and lists of Receiver IDs. */ private HashMap createServicesReceiversMap(Receiver[][] receivers) { HashMap servicesReceiversMap = new HashMap(); for (int i = 0; i < receivers.length; i++) { for (int j = 0; j < receivers[i].length; j++) { if (receivers[i][j] != null) { IOPort port = receivers[i][j].getContainer(); Actor actor = (Actor) port.getContainer(); if (!servicesReceiversMap.containsKey( ((ClientThread) actorsThreadsMap.get(actor)).getService())) { servicesReceiversMap.put( ((ClientThread) actorsThreadsMap.get(actor)).getService(), new LinkedList()); } LinkedList list = (LinkedList) servicesReceiversMap.get( ((ClientThread) actorsThreadsMap.get(actor)).getService()); Integer ID = ((DistributedSDFReceiver) receivers[i][j]).getID(); list.add(ID); } } } return servicesReceiversMap; }
/** * Check for the given channel of the given port to see if variables are needed for recording read * offset and write offset. If the buffer size of a channel divides the readTokens and writeTokens * given in the argument, then there is no need for the variables. Otherwise the integer offsets * are replaced with variables and the code to initialize these variables are generated. * * @param port The port to be checked. * @param channelNumber The channel number. * @param readTokens The number of tokens read. * @param writeTokens The number of tokens written. * @return Code that declares the read and write offset variables. * @exception IllegalActionException If getting the rate or reading parameters throws it. */ protected String _createOffsetVariablesIfNeeded( IOPort port, int channelNumber, int readTokens, int writeTokens) throws IllegalActionException { StringBuffer code = new StringBuffer(); CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(port.getContainer()); int bufferSize = helper.getBufferSize(port, channelNumber); if (bufferSize != 0 && (readTokens % bufferSize != 0 || writeTokens % bufferSize != 0)) { // Increase the buffer size of that channel to the power of two. int newBufferSize = _ceilToPowerOfTwo(bufferSize); helper.setBufferSize(port, channelNumber, newBufferSize); int width; if (port.isInput()) { width = port.getWidth(); } else { width = port.getWidthInside(); } // We check again if the new bufferSize divides readTokens or // writeTokens. If yes, we could avoid using variable to represent // offset. if (readTokens % newBufferSize != 0) { // Declare the read offset variable. StringBuffer channelReadOffset = new StringBuffer(); channelReadOffset.append(CodeGeneratorHelper.generateName(port)); if (width > 1) { channelReadOffset.append("_" + channelNumber); } channelReadOffset.append("_readoffset"); String channelReadOffsetVariable = channelReadOffset.toString(); // code.append("static int " + channelReadOffsetVariable + " = " // + helper.getReadOffset(port, channelNumber) + ";\n"); code.append("static int " + channelReadOffsetVariable + ";\n"); // Now replace the concrete offset with the variable. helper.setReadOffset(port, channelNumber, channelReadOffsetVariable); } if (writeTokens % newBufferSize != 0) { // Declare the write offset variable. StringBuffer channelWriteOffset = new StringBuffer(); channelWriteOffset.append(CodeGeneratorHelper.generateName(port)); if (width > 1) { channelWriteOffset.append("_" + channelNumber); } channelWriteOffset.append("_writeoffset"); String channelWriteOffsetVariable = channelWriteOffset.toString(); code.append("static int " + channelWriteOffsetVariable + ";\n"); // Now replace the concrete offset with the variable. helper.setWriteOffset(port, channelNumber, channelWriteOffsetVariable); } } return code.toString(); }
/** * Create bindings for a set of nodes in a CompositeEntity. The set of nodes can be a subset of * the nodes in the CompositeEntity. Each port on each node yields a binding. * * @param nodes The set of nodes(ComponentEntities). */ public Bindings(Vector nodes) { for (int i = 0; i < nodes.size(); i++) { ComponentEntity actor = (ComponentEntity) (nodes.elementAt(i)); Iterator iter = actor.portList().iterator(); while (iter.hasNext()) { IOPort actorPort = (IOPort) iter.next(); String varLabel = actor.getName() + "." + actorPort.getName(); put(varLabel, null); } } }
/** * Return the local ports whose names match the ports in the specified collection. * * @param ports A collection of ports. * @exception IllegalActionException If no matching port is found. */ private Collection<IOPort> _localMirrors(Collection<IOPort> ports) throws IllegalActionException { Set<IOPort> result = new HashSet<IOPort>(); for (IOPort port : ports) { IOPort localPort = (IOPort) ((Entity) _actor).getPort(port.getName()); if (localPort == null) { throw new IllegalActionException( port.getContainer(), port, "Expected matching port in " + _actor.getFullName()); } result.add(localPort); } return result; }
/** * Construct a trigger event with the specified destination IO port, timestamp, microstep, and * depth. * * @param ioPort The destination IO port. * @param timeStamp The time when the event occurs. * @param microstep The phase of execution within a fixed time. * @param depth The topological depth of the destination IO Port. */ public DEEvent(IOPort ioPort, Time timeStamp, int microstep, int depth) { _actor = (Actor) ioPort.getContainer(); _ioPort = ioPort; _timestamp = timeStamp; _microstep = microstep; _depth = depth; }
/** * Create a guarded communication with a send communication. This constructor allows actors which * are not CSPActors access to CSP functionality by providing their own * ConditionalBranchController. * * @param guard The guard for the guarded communication statement represented by this object. * @param port The IOPort containing the channel (and thus receiver) that this branch will try to * rendezvous with. * @param channel The channel in the IOPort that this branch is trying to rendezvous with. * @param branchID The identification number assigned to this branch upon creation by the * CSPActor. * @param token The token this branch is trying to send. * @param controller The controller that this branch uses. * @exception IllegalActionException If the channel has more than one receiver or if the receiver * is not of type CSPReceiver. */ public ConditionalSend( boolean guard, IOPort port, int channel, int branchID, Token token, ConditionalBranchController controller) throws IllegalActionException { super(guard, port, branchID, controller); _port = port; _channel = channel; try { port.workspace().getReadAccess(); if (!port.isOutput()) { throw new IllegalActionException( port, "ConditionalSend: " + "tokens only sent from an output port."); } if (channel >= port.getWidth() || channel < 0) { throw new IllegalActionException(port, "ConditionalSend: " + "channel index out of range."); } Receiver[][] receivers = port.getRemoteReceivers(); if (receivers == null || receivers[channel] == null) { throw new IllegalActionException( port, "ConditionalSend: " + "Trying to rendezvous with null receiver"); } if (!(receivers[channel][0] instanceof CSPReceiver)) { throw new IllegalActionException( port, "ConditionalSend: " + "channel " + channel + " does not have a receiver " + "of type CSPReceiver."); } _setReceivers(receivers[channel]); } finally { port.workspace().doneReading(); } _setToken(token); }
/** * Return the buffer size of a given channel (i.e, a given port and a given channel number). The * default value is 1. If the port is an output port, then the buffer size is obtained from the * inside receiver. If it is an input port, then it is obtained from the specified port. * * @param port The given port. * @param channelNumber The given channel number. * @return The buffer size of the given channel. * @exception IllegalActionException If the channel number is out of range or if the port is * neither an input nor an output. */ public int getBufferSize(IOPort port, int channelNumber) throws IllegalActionException { Receiver[][] receivers = null; if (port.isInput()) { receivers = port.getReceivers(); } else if (port.isOutput()) { receivers = port.getInsideReceivers(); } // else { // throw new IllegalActionException(port, // "Port is neither an input nor an output."); // } // try { int size = 0; for (int copy = 0; copy < receivers[channelNumber].length; copy++) { int copySize = ((SDFReceiver) receivers[channelNumber][copy]).getCapacity(); if (copySize > size) { size = copySize; } // When an output port of a composite actor is directly // connected to an input port of the same composite actor, // calling getCapacity() will return 0. Therefore we use // the rate to determine the buffer size. if (port.isOutput()) { copySize = DFUtilities.getRate(port); if (copySize > size) { size = copySize; } } } return size; // } // catch (ArrayIndexOutOfBoundsException ex) { // throw new IllegalActionException(port, "Channel out of bounds: " // + channelNumber); // } }
/** * Generate the initialize code for the associated SDF director. * * @return The generated initialize code. * @exception IllegalActionException If the helper associated with an actor throws it while * generating initialize code for the actor. */ public String generateInitializeCode() throws IllegalActionException { StringBuffer code = new StringBuffer(); code.append(super.generateInitializeCode()); ptolemy.actor.CompositeActor container = (ptolemy.actor.CompositeActor) getComponent().getContainer(); CodeGeneratorHelper containerHelper = (CodeGeneratorHelper) _getHelper(container); // Generate code for creating external initial production. Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); int rate = DFUtilities.getTokenInitProduction(outputPort); if (rate > 0) { for (int i = 0; i < outputPort.getWidthInside(); i++) { if (i < outputPort.getWidth()) { String name = outputPort.getName(); if (outputPort.isMultiport()) { name = name + '#' + i; } for (int k = 0; k < rate; k++) { code.append(CodeStream.indent(containerHelper.getReference(name + "," + k))); code.append(" = "); code.append(containerHelper.getReference("@" + name + "," + k)); code.append(";" + _eol); } } } // The offset of the ports connected to the output port is // updated by outside director. _updatePortOffset(outputPort, code, rate); } } return code.toString(); }
/** * Return true if the receiver containing this boundary detector is connected to the inside of an * input boundary port; return false otherwise. A boundary port is an opaque port that is * contained by a composite actor. This method is not synchronized so the caller should be. * * @return True if the containing receiver is connected to the inside of a boundary port; return * false otherwise. * @exception IllegalActionException * @exception InvalidStateException */ public boolean isConnectedToBoundaryInside() throws InvalidStateException, IllegalActionException { if (_connectedInsideOfBoundaryCacheIsOn) { return _isConnectedInsideOfBoundaryValue; } else { IOPort contPort = _receiver.getContainer(); if (contPort == null) { _connectedInsideOfBoundaryCacheIsOn = false; _isConnectedInsideOfBoundaryValue = false; return _isConnectedInsideOfBoundaryValue; } ComponentEntity contEntity = (ComponentEntity) contPort.getContainer(); IOPort connectedPort = null; ComponentEntity connectedEntity = null; Iterator ports = contPort.connectedPortList().iterator(); while (ports.hasNext()) { connectedPort = (IOPort) ports.next(); connectedEntity = (ComponentEntity) connectedPort.getContainer(); if ((connectedEntity == contEntity.getContainer()) && connectedPort.isInput() && connectedPort.isOpaque()) { // The port container of this receiver is // connected to the inside of a boundary port. // Now determine if this receiver's channel is // connected to the boundary port. Receiver[][] receivers = connectedPort.deepGetReceivers(); for (int i = 0; i < receivers.length; i++) { for (int j = 0; j < receivers[i].length; j++) { if (_receiver == receivers[i][j]) { _connectedInsideOfBoundaryCacheIsOn = true; _isConnectedInsideOfBoundaryValue = true; return true; } } } } } _connectedInsideOfBoundaryCacheIsOn = true; _isConnectedInsideOfBoundaryValue = false; return _isConnectedInsideOfBoundaryValue; } }
/** * If the argument is true, make the port a multiport. If the argument is false, make the port not * a multiport. This method overrides the base class to make the same change on the mirror ports * in the controller and state refinments. This method invalidates the schedule and resolved types * of the director of the container, if there is one. It is write-synchronized on the workspace, * and increments the version of the workspace. * * @param isMultiport True to make the port a multiport. * @exception IllegalActionException If changing the port status is not permitted. */ @Override public void setMultiport(boolean isMultiport) throws IllegalActionException { boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); if (_mirrorDisable || getContainer() == null) { // Have already called the super class. // This time, process the request. // process request for the sibling if (_hasSibling && isOutput() && getContainer() != null) { TransitionRefinement container = (TransitionRefinement) getContainer(); TransitionRefinementPort sibling = (TransitionRefinementPort) container.getPort(getName() + "_in"); sibling._mirrorDisable = true; sibling.setMultiport(isMultiport); sibling._mirrorDisable = false; } super.setMultiport(isMultiport); } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port instanceof IOPort) { ((IOPort) port).setMultiport(isMultiport); success = true; } } } if (!success) { super.setMultiport(isMultiport); } } } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Return true if the receiver containing this boundary detector is contained on the outside of a * boundary port. A boundary port is an opaque port that is contained by a composite actor. If the * containing receiver is contained on the outside of a boundary port then return true; otherwise * return false. This method is not synchronized so the caller should be. * * @return True if the containing receiver is contained on the outside of a boundary port; return * false otherwise. */ public boolean isOutsideBoundary() { if (_outsideBoundaryCacheIsOn) { return _isInsideBoundaryValue; } else { IOPort innerPort = _receiver.getContainer(); if (innerPort == null) { _outsideBoundaryCacheIsOn = false; _isOutsideBoundaryValue = false; return _isOutsideBoundaryValue; } ComponentEntity innerEntity = (ComponentEntity) innerPort.getContainer(); if ((innerEntity != null) && !innerEntity.isAtomic() && innerPort.isOpaque()) { // The containing receiver is contained by the port // of a composite actor. if (innerPort.isOutput() && !innerPort.isInput()) { _isOutsideBoundaryValue = false; } else if (!innerPort.isOutput() && innerPort.isInput()) { _isOutsideBoundaryValue = true; } else if (!innerPort.isOutput() && !innerPort.isInput()) { _isOutsideBoundaryValue = false; } else { // CONCERN: The following only works if the port // is not both an input and output. throw new IllegalArgumentException( "A port that " + "is both an input and output can not be " + "properly dealt with by " + "PNQueueReceiver.isInsideBoundary"); } _outsideBoundaryCacheIsOn = true; return _isOutsideBoundaryValue; } _outsideBoundaryCacheIsOn = true; _isOutsideBoundaryValue = false; return _isOutsideBoundaryValue; } }
/** * Check to see if the buffer size for the current schedule is greater than the previous size. If * so, set the buffer size to the current buffer size needed. * * @exception IllegalActionException If thrown while getting helper or buffer size. */ protected void _updatePortBufferSize() throws IllegalActionException { ptolemy.domains.sdf.kernel.SDFDirector director = (ptolemy.domains.sdf.kernel.SDFDirector) getComponent(); CompositeActor container = (CompositeActor) director.getContainer(); ptolemy.codegen.c.actor.TypedCompositeActor containerHelper = (ptolemy.codegen.c.actor.TypedCompositeActor) _getHelper(container); Iterator actors = container.deepEntityList().iterator(); while (actors.hasNext()) { Actor actor = (Actor) actors.next(); CodeGeneratorHelper actorHelper = (CodeGeneratorHelper) _getHelper((NamedObj) actor); Iterator inputPorts = actor.inputPortList().iterator(); while (inputPorts.hasNext()) { IOPort inputPort = (IOPort) inputPorts.next(); for (int k = 0; k < inputPort.getWidth(); k++) { int newCapacity = getBufferSize(inputPort, k); int oldCapacity = actorHelper.getBufferSize(inputPort, k); if (newCapacity > oldCapacity) { actorHelper.setBufferSize(inputPort, k, newCapacity); } } } } Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); for (int k = 0; k < outputPort.getWidthInside(); k++) { int newCapacity = getBufferSize(outputPort, k); int oldCapacity = containerHelper.getBufferSize(outputPort, k); if (newCapacity > oldCapacity) { containerHelper.setBufferSize(outputPort, k, newCapacity); } } } }
/** * Move this object up by one in the list of attributes of the container. If this object is * already first, do nothing. This method overrides the base class to mirror the change in any * mirror ports. Increment the version of the workspace. * * @return The index of the specified object prior to moving it, or -1 if it is not moved. * @exception IllegalActionException If this object has no container. */ public int moveUp() throws IllegalActionException { boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); int result = -1; if (_mirrorDisable || (getContainer() == null)) { result = super.moveUp(); } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port instanceof IOPort) { ((IOPort) port).moveUp(); success = true; } } } // The mirror port(s), if there are any, // will have called this method and achieved // the moveUp. But if there are no mirror // ports, we need to do it here. if (!success) { result = super.moveUp(); } } return result; } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Return the director that created this receiver. If this receiver is an inside receiver of an * output port of an opaque composite actor, then the director will be the local director of the * container of its port. Otherwise, it's the executive director of the container of its port.Note * that the director returned is guaranteed to be non-null. This method is read synchronized on * the workspace. * * @return An instance of DEDirector. * @exception IllegalActionException If there is no container port, or if the port has no * container actor, or if the actor has no director, or if the director is not an instance of * DEDirector. */ private DEDirector _getDirector() throws IllegalActionException { IOPort port = getContainer(); if (port != null) { if (_directorVersion == port.workspace().getVersion()) { return _director; } // Cache is invalid. Reconstruct it. try { port.workspace().getReadAccess(); Actor actor = (Actor) port.getContainer(); if (actor != null) { Director dir; if (!port.isInput() && (actor instanceof CompositeActor) && ((CompositeActor) actor).isOpaque()) { dir = actor.getDirector(); } else { dir = actor.getExecutiveDirector(); } if (dir != null) { if (dir instanceof DEDirector) { _director = (DEDirector) dir; _directorVersion = port.workspace().getVersion(); return _director; } else { throw new IllegalActionException(getContainer(), "Does not have a DEDirector."); } } } } finally { port.workspace().doneReading(); } } throw new IllegalActionException( getContainer(), "Does not have a IOPort as the container of the receiver."); }
/** * Move this object to the last position in the list of attributes of the container. If this * object is already last, do nothing. This method overrides the base class to mirror the change * in any mirror ports. Increment the version of the workspace. * * @return The index of the specified object prior to moving it, or -1 if it is not moved. * @exception IllegalActionException If this object has no container. */ public int moveToLast() throws IllegalActionException { boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); int result = -1; if (_mirrorDisable || (getContainer() == null)) { result = super.moveToLast(); } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port instanceof IOPort) { ((IOPort) port).moveToLast(); success = true; } } } if (!success) { result = super.moveToLast(); } } return result; } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Return the list of sending (up-stream) ports that are connected to the specified port. This * treats every port as an opaque port. * * @param port The specified port. * @return The list of sending ports. */ protected static List<IOPort> _getSourcePortList(IOPort port) { List<IOPort> result = new ArrayList<IOPort>(); for (IOPort connectedPort : (List<IOPort>) port.connectedPortList()) { boolean isInput = connectedPort.isInput(); boolean isCompositeInput = connectedPort.getContainer() instanceof CompositeEntity && isInput && port.depthInHierarchy() > connectedPort.depthInHierarchy(); if (!isInput || isCompositeInput) { result.add(connectedPort); } } return result; }
/** * If the argument is true, make the port an input port. If the argument is false, make the port * not an input port. This method overrides the base class to make the same change on the mirror * ports in the controller and state refinments. This method invalidates the schedule and resolved * types of the director of the container, if there is one. It is write-synchronized on the * workspace, and increments the version of the workspace. * * @param isInput True to make the port an input. * @exception IllegalActionException If changing the port status is not permitted. */ @Override public void setInput(boolean isInput) throws IllegalActionException { boolean disableStatus = _mirrorDisable; try { _workspace.getWriteAccess(); if (_mirrorDisable || getContainer() == null) { // Have already called the super class. // This time, process the request. super.setInput(isInput); } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port instanceof IOPort) { ((IOPort) port).setInput(isInput); success = true; } } } if (!success) { super.setInput(isInput); } } } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Put a token on the queue contained in this receiver. If the queue is full, then suspend the * calling thread (blocking write) and inform the director of the same. Resume the process on * detecting room in the queue. If a termination is requested, then initiate the termination of * the calling process by throwing a TerminateProcessException. On detecting a room in the queue, * put a token in the queue. Check whether any process is blocked on a read from this receiver. If * a process is indeed blocked, then unblock the process, and inform the director of the same. * * @param token The token to be put in the receiver, or null to not put anything. * @exception NoRoomException If during initialization, capacity cannot be increased enough to * accommodate initial tokens. */ public void put(Token token) throws NoRoomException { IOPort port = getContainer(); if (port == null || token == null) { return; // Nothing to do. } Workspace workspace = port.workspace(); while (!_terminate) { int depth = 0; try { // NOTE: Avoid acquiring read access on the workspace // while holding the lock on the director because if // some other process is trying to acquire write access, // the request for read access will be deferred. Nameable container = getContainer().getContainer(); Manager manager = ((Actor) container).getManager(); // NOTE: This used to synchronize on this, but since it calls // director methods that are synchronized on the director, // this can cause deadlock. synchronized (_director) { // Need to check this again after acquiring the lock. // Otherwise, could end up calling wait() below _after_ // notification has occurred. if (_terminate) { break; } // If we are in the initialization phase, then we may have // to increase the queue capacity before proceeding. This // may be needed to support PublisherPorts that produce // initial tokens (or, I suppose, any actor that produces // initial tokens during initialize()?). if (!super.hasRoom()) { if (container instanceof Actor) { if (manager.getState().equals(Manager.INITIALIZING)) { try { _queue.setCapacity(_queue.getCapacity() + 1); } catch (IllegalActionException e) { throw new NoRoomException( getContainer(), "Failed to increase queue capacity enough to accommodate initial tokens"); } } } } // Try to write. if (super.hasRoom()) { super.put(token); // If any thread is blocked on a get(), then it will become // unblocked. Notify the director now so that there isn't a // spurious deadlock detection. if (_readPending != null) { _director.threadUnblocked(_readPending, this, PNDirector.READ_BLOCKED); _readPending = null; } // Normally, the _writePending reference will have // been cleared by the read that unblocked this write. // However, it might be that the director increased the // buffer size, which would also have the affect of unblocking // this write. Hence, we clear it here if it is set. if (_writePending != null) { _director.threadUnblocked(_writePending, this, PNDirector.WRITE_BLOCKED); _writePending = null; } break; } // Wait to try again. _writePending = Thread.currentThread(); _director.threadBlocked(_writePending, this, PNDirector.WRITE_BLOCKED); // NOTE: We cannot use workspace.wait(Object) here without // introducing a race condition, because we have to release // the lock on the _director before calling workspace.wait(_director). depth = workspace.releaseReadPermission(); _director.wait(); } // release lock on _director before reacquiring read permissions. } catch (InterruptedException e) { _terminate = true; } finally { if (depth > 0) { workspace.reacquireReadPermission(depth); } } } if (_terminate) { throw new TerminateProcessException("Process terminated."); } }
/** * If the argument is true, make the port an output port. If the argument is false, make the port * not an output port. In addition, if the container is an instance of Refinement, and the * argument is true, find the corresponding port of the controller and make it an input and not an * output. This makes it possible for the controller to see the outputs of the refinements. This * method overrides the base class to make the same change on the mirror ports in the controller * and state refinments. This method invalidates the schedule and resolved types of the director * of the container, if there is one. It is write-synchronized on the workspace, and increments * the version of the workspace. * * @param isOutput True to make the port an output. * @exception IllegalActionException If changing the port status is not permitted. */ public void setOutput(boolean isOutput) throws IllegalActionException { boolean disableStatus = _mirrorDisable; // check first that this isn't an input sibling port, // if it is then it *cannot* be set as an output too if (_hasSibling && isInput() && !isOutput()) { if (isOutput) { throw new InternalErrorException( "TransitionRefinementPort.setOutput:" + " cannot set input sibling port to be an output"); } else { return; } } try { _workspace.getWriteAccess(); if (_mirrorDisable || (getContainer() == null)) { // Have already called the super class. // This time, process the request. super.setOutput(isOutput); // now create a sibling if we // don't otherwise have one if (!_hasSibling && isOutput) { try { TransitionRefinement container = (TransitionRefinement) getContainer(); TransitionRefinementPort sibling = new TransitionRefinementPort(container, getName() + "_in"); sibling._hasSibling = true; sibling._mirrorDisable = true; // set attributes of sibling sibling.setInput(true); sibling.setMultiport(isMultiport()); sibling._mirrorDisable = false; // link the port relation should already exist // from this port's creation in newPort() String relationName = getName() + "Relation"; ModalModel model = (ModalModel) container.getContainer(); Relation relation = model.getRelation(relationName); if (relation != null) { sibling.link(relation); } _hasSibling = true; } catch (IllegalActionException ex) { throw new InternalErrorException( "TransitionRefinementPort.setOutput: Internal error: " + ex.getMessage()); } catch (NameDuplicationException ex) { throw new InternalErrorException( "TransitionRefinementPort.setOutput: Internal error: " + ex.getMessage()); } } } else { _mirrorDisable = true; boolean success = false; Nameable container = getContainer(); if (container != null) { Nameable modal = container.getContainer(); if (modal instanceof ModalModel) { Port port = ((ModalModel) modal).getPort(getName()); if (port instanceof IOPort) { ((IOPort) port).setOutput(isOutput); success = true; } } } if (!success) { super.setOutput(isOutput); } } } finally { _mirrorDisable = disableStatus; _workspace.doneWriting(); } }
/** * Generate code for the firing of refinements. * * @param code The string buffer that the generated code is appended to. * @exception IllegalActionException If the helper associated with an actor throws it while * generating fire code for the actor. */ protected void _generateRefinementCode(StringBuffer code) throws IllegalActionException { ptolemy.domains.fsm.kernel.FSMDirector director = (ptolemy.domains.fsm.kernel.FSMDirector) getComponent(); ptolemy.domains.fsm.kernel.FSMActor controller = director.getController(); FSMActor controllerHelper = (FSMActor) _getHelper(controller); int depth = 1; code.append(_getIndentPrefix(depth)); code.append( "switch (" + controllerHelper.processCode("$actorSymbol(currentState)") + ") {" + _eol); Iterator states = controller.entityList().iterator(); int stateCount = 0; depth++; while (states.hasNext()) { code.append(_getIndentPrefix(depth)); code.append("case " + stateCount + ":" + _eol); stateCount++; depth++; State state = (State) states.next(); Actor[] actors = state.getRefinement(); if (actors != null) { for (int i = 0; i < actors.length; i++) { CodeGeneratorHelper actorHelper = (CodeGeneratorHelper) _getHelper((NamedObj) actors[i]); // fire the actor // code.append(actorHelper.generateFireCode()); code.append(_getActorName(actors[i]) + "();" + _eol); // update buffer offset after firing each actor once int[][] rates = actorHelper.getRates(); Iterator ports = ((Entity) actors[i]).portList().iterator(); int portNumber = 0; while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); if (rates != null) { code.append( "switch (" + actorHelper.processCode("$actorSymbol(" + "currentConfiguration)") + ") {" + _eol); for (int k = 0; k < rates.length; k++) { code.append("case " + k + ":" + _eol); if (rates[k] != null) { int rate = rates[k][portNumber]; if (port.isInput()) { _updatePortOffset(port, code, rate); } else { _updateConnectedPortsOffset(port, code, rate); } code.append("break;" + _eol); } } code.append("}" + _eol); } else { int rate = DFUtilities.getRate(port); if (port.isInput()) { _updatePortOffset(port, code, rate); } else { _updateConnectedPortsOffset(port, code, rate); } } portNumber++; } } } code.append(_getIndentPrefix(depth)); code.append("break;" + _eol); // end of case statement depth--; } depth--; code.append(_getIndentPrefix(depth)); code.append("}" + _eol); // end of switch statement }
// Expand the P-APGAN-clustered graph. The schedule element that is // returned has an iteration count of 1. This iteration count expression // can be changed by the caller to iterate the schedule computed in // this method. // @param graph The graph containing the node. // @param node The super node to expand. // @param apgan The scheduler that was used to build the cluster hierarchy. // @return The schedule saving the expansion result. private SymbolicScheduleElement _expandAPGAN( PSDFGraph graph, ptolemy.graph.Node node, PSDFAPGANStrategy strategy) { PSDFGraph childGraph = (PSDFGraph) strategy.getClusterManager().getSubgraph(node); try { // Atomic node if (childGraph == null) { PSDFNodeWeight weight = (PSDFNodeWeight) node.getWeight(); SymbolicFiring firing = new SymbolicFiring((Actor) weight.getComputation(), "1"); return firing; // Super node } else { // FIXME: why call new Schedule here? /*Schedule schedule = */ new Schedule(); // Expand the super node with adjacent nodes contained // within it. Edge edge = (Edge) childGraph.edges().iterator().next(); ptolemy.graph.Node source = edge.source(); ptolemy.graph.Node sink = edge.sink(); SymbolicScheduleElement first = _expandAPGAN(childGraph, source, strategy); SymbolicScheduleElement second = _expandAPGAN(childGraph, sink, strategy); // Determine the iteration counts of the source and // sink clusters. String producedExpression = strategy.producedExpression(edge); String consumedExpression = strategy.consumedExpression(edge); // These errors should not occur. if (producedExpression == null) { throw new RuntimeException( "Internal error: null " + "production rate expression. The offending edge " + "follows.\n" + edge); } else if (consumedExpression == null) { throw new RuntimeException( "Internal error: null " + "consumption rate expression. The offending edge " + "follows.\n" + edge); } String denominator = PSDFGraphs.gcdExpression(producedExpression, consumedExpression); String firstIterations = "(" + consumedExpression + ") / (" + denominator + ")"; String secondIterations = "(" + producedExpression + ") / (" + denominator + ")"; first.setIterationCount(firstIterations); second.setIterationCount(secondIterations); SymbolicSchedule symbolicSchedule = new SymbolicSchedule("1"); symbolicSchedule.add((ScheduleElement) first); symbolicSchedule.add((ScheduleElement) second); // Compute buffer sizes and associate them with the // corresponding relations. Iterator edges = childGraph.edges().iterator(); while (edges.hasNext()) { Edge nextEdge = (Edge) edges.next(); PSDFEdgeWeight weight = (PSDFEdgeWeight) nextEdge.getWeight(); IOPort sourcePort = weight.getSourcePort(); List relationList = sourcePort.linkedRelationList(); if (relationList.size() != 1) { // FIXME: Need to generalize this? throw new RuntimeException( "Cannot handle relation " + "lists that are not singletons.\n" + "The size of this relation list is " + relationList.size() + "\nA dump of the offending edge follows.\n" + nextEdge + "\n"); } Iterator relations = relationList.iterator(); Relation relation = (Relation) relations.next(); String produced = strategy.producedExpression(nextEdge); String consumed = strategy.consumedExpression(nextEdge); String bufferSizeExpression = "((" + produced + ") * (" + consumed + ")) / " + PSDFGraphs.gcdExpression(produced, consumed); // Due to the bottom-up traversal in _expandAPGAN, // relations that are linked to multiple sink // nodes will have their buffer sizes // progressively replaced by those of outer // clusterings, and will end up with the buffer // size determined by the outermost clustering. _debug( "Associating buffer size expression '" + bufferSizeExpression + "' with relation '" + relation.getName() + "'\n"); _bufferSizeMap.put(relation, bufferSizeExpression); } return symbolicSchedule; } } catch (Throwable throwable) { throw new KernelRuntimeException( throwable, "Error converting cluster hierarchy to " + "schedule.\n"); } }
/** * Return the parameterized scheduling sequence. An exception will be thrown if the graph is not * schedulable. * * @return A schedule of the deeply contained opaque entities in the firing order. * @exception NotSchedulableException If a parameterized schedule cannot be derived for the model. * @exception IllegalActionException If the rate parameters of the model are not correct, or the * computed rates for external ports are not correct. */ @SuppressWarnings("unused") protected Schedule _getSchedule() throws NotSchedulableException, IllegalActionException { PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor model = (CompositeActor) director.getContainer(); // Get the vectorization factor. String vectorizationFactorExpression = "1"; String vectorizationName = director.vectorizationFactor.getName(model); vectorizationFactorExpression = vectorizationName.replaceAll("\\.", "::"); if (vectorizationFactorExpression.indexOf(" ") != -1) { throw new InternalErrorException( "The vectorizationFactor " + "PSDFDirector parameter must " + "not have spaces in its value. The original value " + "was \"" + vectorizationName + "\". Try changing the name of " + "director."); } PSDFGraphReader graphReader = new PSDFGraphReader(); PSDFGraph graph = (PSDFGraph) graphReader.convert(model); _debug("PSDF graph = \n" + graph.toString()); if (_debugFlag) { graph.printEdgeRateExpressions(); } PSDFAPGANStrategy strategy = new PSDFAPGANStrategy(graph); ptolemy.graph.sched.Schedule graphSchedule = strategy.schedule(); _debug("P-APGAN schedule = \n" + graphSchedule.toString()); SymbolicScheduleElement resultSchedule = _expandAPGAN(graph, strategy.getClusterManager().getRootNode(), strategy); resultSchedule.setIterationCount(vectorizationFactorExpression); _debug("Final schedule = \n" + resultSchedule.toString()); if (_debugging) { _debug("The buffer size map:\n"); Iterator relations = _bufferSizeMap.keySet().iterator(); while (relations.hasNext()) { Relation relation = (Relation) relations.next(); _debug(relation.getName() + ": " + _bufferSizeMap.get(relation) + "\n"); } } _saveBufferSizes(_bufferSizeMap); // Crazy hack to infer firing counts for each actor. try { _inferFiringCounts(resultSchedule, null); } catch (NameDuplicationException ex) { throw new NotSchedulableException(new LinkedList(), ex, "Error recording firing counts"); } // Crazy hack to Infer port production: FIXME: This should be // done as part of the APGAN expansion where the rates of // external ports are unknown The reason is that it will make // rate information propagate from an actor input port to // another actors input port that are connected on the inside // to the same external input port. See // BaseSDFScheduler.setContainerRates. Iterator ports = model.portList().iterator(); while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); if (_debugging && VERBOSE) { _debug("External Port " + port.getName()); } if (port.isInput() && port.isOutput()) { throw new NotSchedulableException( port, "External port is both an input and an output, " + "which is not allowed in SDF."); } else if (port.isInput()) { List sinks = port.insideSinkPortList(); if (sinks.size() > 0) { IOPort connectedPort = (IOPort) sinks.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); String sinkExpression; Variable sinkRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenConsumptionRate"); if (sinkRateVariable == null) { sinkExpression = "1"; } else { sinkExpression = identifier + "::" + sinkRateVariable.getName(); } String expression = sinkExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenConsumptionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenConsumptionRate to " + expression); } } } else if (port.isOutput()) { List sources = port.insideSourcePortList(); if (sources.size() > 0) { IOPort connectedPort = (IOPort) sources.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); Variable sourceRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenProductionRate"); String sourceExpression; if (sourceRateVariable == null) { sourceExpression = "1"; } else { sourceExpression = identifier + "::" + sourceRateVariable.getName(); } String expression = sourceExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenProductionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenProductionRate to " + expression); } } // Infer init production. // Note that this is a very simple type of inference... // However, in general, we don't want to try to // flatten this model... // Iterator connectedPorts = // port.insideSourcePortList().iterator(); // IOPort foundOutputPort = null; // int inferredRate = 0; // while (connectedPorts.hasNext()) { // IOPort connectedPort = (IOPort) connectedPorts.next(); // int newRate; // if (connectedPort.isOutput()) { // newRate = // DFUtilities.getTokenInitProduction(connectedPort); // } else { // newRate = 0; // } // // If we've already set the rate, then check that the // // rate for any other internal port is correct. // if (foundOutputPort != null && // newRate != inferredRate) { // throw new NotSchedulableException( // "External output port " + port // + " is connected on the inside to ports " // + "with different initial production: " // + foundOutputPort + " and " // + connectedPort); // } // foundOutputPort = connectedPort; // inferredRate = newRate; // } // DFUtilities._setIfNotDefined( // port, "tokenInitProduction", inferredRate); // if (_debugging && VERBOSE) { // _debug("Setting tokenInitProduction to " // + inferredRate); // } } else { throw new NotSchedulableException( port, "External port is neither an input and an output, " + "which is not allowed in SDF."); } } // Set the schedule to be valid. setValid(true); if (resultSchedule instanceof Schedule) { return (Schedule) resultSchedule; } else { // Must be ScheduleElement. Schedule schedule = new Schedule(); schedule.add((ScheduleElement) resultSchedule); return schedule; } }
/** * Return the dependency between the specified input port and the specified output port. This is * done by checking the guards and actions of all the transitions. When called for the first time * since a change in the model structure, this method performs the complete analysis of the FSM * and caches the result. Subsequent calls just look up the result. * * @param input The input port. * @param output The output port, or null to update the dependencies (and record equivalence * classes) without requiring there to be an output port. * @return The dependency between the specified input port and the specified output port, or null * if a null output is port specified. * @exception IllegalActionException If a guard expression cannot be parsed. */ public Dependency getDependency(IOPort input, IOPort output) throws IllegalActionException { // If the dependency is not up-to-date, then update it. long workspaceVersion = ((NamedObj) _actor).workspace().getVersion(); if (_dependencyVersion != workspaceVersion) { // Need to update dependencies. The cached version // is obsolete. try { ((NamedObj) _actor).workspace().getReadAccess(); _reverseDependencies = new HashMap<IOPort, Map<IOPort, Dependency>>(); _forwardDependencies = new HashMap<IOPort, Map<IOPort, Dependency>>(); // Iterate over all the associated interfaces. for (CausalityInterface causality : _composedInterfaces) { List<IOPort> mirrorInputs = causality.getActor().inputPortList(); for (IOPort mirrorInput : mirrorInputs) { Port localInput = ((Entity) _actor).getPort(mirrorInput.getName()); if (!(localInput instanceof IOPort)) { throw new IllegalActionException( _actor, mirrorInput.getContainer(), "No matching port with name " + mirrorInput.getName()); } // The localInput may not be an input port... // It may have been an output port that the FSMActor controller // also has as an input port. But we don't want to set a forward // depedency in this case. if (!((IOPort) localInput).isInput()) { continue; } Map<IOPort, Dependency> forwardMap = _forwardDependencies.get(localInput); if (forwardMap == null) { forwardMap = new HashMap<IOPort, Dependency>(); _forwardDependencies.put((IOPort) localInput, forwardMap); } for (IOPort dependentOutput : causality.dependentPorts(mirrorInput)) { Port localOutput = ((Entity) _actor).getPort(dependentOutput.getName()); if (!(localOutput instanceof IOPort)) { throw new IllegalActionException( _actor, mirrorInput.getContainer(), "No matching port with name " + mirrorInput.getName()); } Dependency dependency = causality.getDependency(mirrorInput, dependentOutput); forwardMap.put((IOPort) localOutput, dependency); // Now handle the reverse dependencies. Map<IOPort, Dependency> backwardMap = _reverseDependencies.get(localOutput); if (backwardMap == null) { backwardMap = new HashMap<IOPort, Dependency>(); _reverseDependencies.put((IOPort) localOutput, backwardMap); } backwardMap.put((IOPort) localInput, dependency); } } } // Next do equivalence classes. // We iterate over the input ports, and for each one, // find the ports for which it has equivalents in any // associated causality. _equivalenceClasses = new HashMap<IOPort, Collection<IOPort>>(); Collection<IOPort> localInputs = _actor.inputPortList(); for (IOPort localInput : localInputs) { Collection<IOPort> equivalences = _equivalenceClasses.get(localInput); if (equivalences != null) { // This input port is done. continue; } equivalences = new HashSet<IOPort>(); // Iterate over all the associated interfaces. for (CausalityInterface causality : _composedInterfaces) { IOPort mirrorInput = (IOPort) ((Entity) causality.getActor()).getPort(localInput.getName()); if (mirrorInput == null) { throw new IllegalActionException( _actor, localInput, "Expected matching port in " + causality.getActor().getFullName()); } equivalences.addAll(_localMirrors(causality.equivalentPorts(mirrorInput))); } // Set the equivalence class for all ports in the set. for (IOPort equivalentPort : equivalences) { _equivalenceClasses.put(equivalentPort, equivalences); } } } finally { ((NamedObj) _actor).workspace().doneReading(); } _dependencyVersion = workspaceVersion; } if (output == null) { return null; } Map<IOPort, Dependency> inputMap = _forwardDependencies.get(input); if (inputMap != null) { Dependency result = inputMap.get(output); if (result != null) { return result; } } // If there is no recorded dependency, then reply // with the additive identity (which indicates no // dependency). return _defaultDependency.oPlusIdentity(); }
/** * Read the control token input, transfer input tokens, and invoke prefire() of the selected * refinement. * * @exception IllegalActionException If there is no director, or if the director's prefire() * method throws it, or if this actor is not opaque. */ public boolean prefire() throws IllegalActionException { if (_debugging) { _debug("Calling prefire()"); } try { _workspace.getReadAccess(); super.prefire(); Case container = (Case) getContainer(); // Read from port parameters, including the control port. Iterator portParameters = container.attributeList(PortParameter.class).iterator(); while (portParameters.hasNext()) { PortParameter portParameter = (PortParameter) portParameters.next(); portParameter.update(); } String controlValue = container.control.getToken().toString(); ComponentEntity refinement = container.getEntity(controlValue); if (!(refinement instanceof Refinement)) { refinement = container._default; } container._current = (Refinement) refinement; // Transfer input tokens. for (Iterator inputPorts = container.inputPortList().iterator(); inputPorts.hasNext() && !_stopRequested; ) { IOPort port = (IOPort) inputPorts.next(); if (!(port instanceof ParameterPort)) { Receiver[][] insideReceivers = port.deepGetReceivers(); for (int i = 0; i < port.getWidth(); i++) { if (port.hasToken(i)) { Token token = port.get(i); if ((insideReceivers != null) && (insideReceivers[i] != null)) { for (int j = 0; j < insideReceivers[i].length; j++) { if (insideReceivers[i][j].getContainer().getContainer() == refinement) { insideReceivers[i][j].put(token); if (_debugging) { _debug( getFullName(), "transferring input from " + port.getFullName() + " to " + (insideReceivers[i][j]).getContainer().getFullName()); } } } } } } } } if (_stopRequested) { return false; } return container._current.prefire(); } finally { _workspace.doneReading(); } }