Ejemplo n.º 1
0
  /**
   * 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;
  }
Ejemplo n.º 2
0
  /**
   * 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);
        }
      }
    }
  }
Ejemplo n.º 3
0
 /** 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());
 }
Ejemplo n.º 4
0
 /** @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;
 }
Ejemplo n.º 5
0
  /**
   * 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();
    }
  }
Ejemplo n.º 6
0
  /**
   * 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;
    }
  }
Ejemplo n.º 7
0
  /**
   * 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;
  }
Ejemplo n.º 8
0
  /**
   * 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();
  }
Ejemplo n.º 9
0
  /**
   * 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);
      }
    }
  }
Ejemplo n.º 10
0
 /**
  * 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;
 }
Ejemplo n.º 11
0
 /**
  * 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;
 }
Ejemplo n.º 12
0
  /**
   * 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);
  }
Ejemplo n.º 13
0
  /**
   * 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);
    // }
  }
Ejemplo n.º 14
0
  /**
   * 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();
  }
Ejemplo n.º 15
0
  /**
   * 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();
    }
  }
Ejemplo n.º 17
0
  /**
   * 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;
    }
  }
Ejemplo n.º 18
0
  /**
   * 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();
    }
  }
Ejemplo n.º 20
0
  /**
   * 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();
    }
  }
Ejemplo n.º 22
0
  /**
   * 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();
    }
  }
Ejemplo n.º 24
0
  /**
   * 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();
    }
  }
Ejemplo n.º 26
0
  /**
   * 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
  }
Ejemplo n.º 27
0
  // 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");
    }
  }
Ejemplo n.º 28
0
  /**
   * 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;
    }
  }
Ejemplo n.º 29
0
  /**
   * 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();
  }
Ejemplo n.º 30
0
  /**
   * 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();
    }
  }