Class ThreadedComposite

  • All Implemented Interfaces:
    java.lang.Cloneable, Actor, Executable, FiringsRecordable, Initializable, TypedActor, Changeable, Debuggable, DebugListener, Derivable, Instantiable, ModelErrorHandler, MoMLExportable, Moveable, Nameable, HandlesInternalLinks

    public class ThreadedComposite
    extends MirrorComposite
    A container for another actor that executes that other actor in a separate thread called the inside thread. This actor starts that thread in its initialize() method, which is invoked by its executive director (the director in charge of firing this actor). The thread that invokes the action methods of this actor (initialize(), prefire(), fire(), postfire(), and wrapup()) is called the director thread.

    A paper describing the use of this actor is found at http://www.eecs.berkeley.edu/Pubs/TechRpts/2008/EECS-2008-151.html.

    To use this actor in Vergil, drag a ThreadedComposite on to the canvas and then drag the actor to be contained on to the ThreadedComposite actor.

    This actor automatically creates input and output ports to match those of the inside actor. Input events provided at those input ports are provided as input events to the contained actor. Outputs provided by the contained actor become output events of this actor. The time stamp of the input events is provided by the container of this actor. The time stamp of the output events depends on the delay parameter, as explained below.

    The inside thread blocks waiting for inputs or pure events. Inputs are provided to that thread when the fire() method of this actor is invoked by the director thread. Pure events are provided after fireAt(), fireAtCurrentTime(), or fireAtFirstValidTimeAfter() are called by either the inside thread or the director thread. When the time of those firing requests becomes current time, the container will (presumably) fire this actor, and this actor will provide a pure event to the inside thread, causing it to fire the contained actor.

    If the synchronizeToRealTime parameter is true, then when the inside thread encounters an input or pure event with time stamp t, it stalls until real time matches or exceeds t (measured in seconds since the start of execution of the inside thread). In contrast for example to the synchronizeToRealTime parameter of the DEDirector, this enables construction of models where only a portion of the model synchronizes to real time.

    When the wrapup() method of this actor is called, the inside thread is provided with signal to terminate rather than to process additional inputs. The inside thread will also exit if stop() is called on this actor; however, in this case, which iterations are completed is nondeterminate (there may be inputs left unprocessed). If any inside actor return false from postfire(), then the inside thread will also terminate and this actor will return false from postfire.

    The parameters of this actor include all the parameters of the contained actor, and setting those parameters automatically sets the parameters of the contained actor.

    In addition to the parameters of the contained actor, this actor has a delay parameter. This parameter is a double that be any nonnegative value or the special value UNDEFINED. If it is given a nonnegative value, then the value specifies the model-time delay between input events and the output events that result from reacting to those input events. That is, if this actor is given an input event with time stamp t, then if the contained actor produces any output events in reaction to that event, those output events will be produced by this actor with time stamp t + delay.

    If delay has value UNDEFINED, then outputs are produced at the current model time of the executive director when the inside thread happens to produce those events, or if synchronizeToRealTime, at the greater of current model time and current real time (measured in seconds since the start of execution). This is accomplished by the inside thread calling fireAtFirstValidTimeAfter() of the enclosing director, and then producing the outputs when the requested firing occurs in the director thread. Note that with this value of the delay, it is possible for the inside thread to continue to execute and respond to input events after the wrapup phase of the director thread has been entered. The wrapup phase will stall until the inside thread has completed its processing of its inputs, but any outputs it produces after the wrapup phase has started will be discarded.

    The most common use of this actor is in the DE domain, although it can also be used in CT, SR, SDF, and other domains, with some care. See the above referenced memo. Regardless of the value of delay, this actor is treated by DE as introducing a delay, much like the TimedDelay actor. In fact, if delay is 0.0, there will be a one tick delay in superdense time, just as with the TimedDelay actor. If the inside model also has a time delay (e.g. if you put a TimedDelay actor inside a ThreadedComposite), then the total delay is the sum of the two delays.

    Discussion:

    There are several useful things you can do with this model. We describe some use cases here:

    Background execution. When delay is greater than or equal to 0.0, then when this actor is fired in response to input events with time stamp t, the actual processing of those events occurs later in a separate thread. The director thread is not blocked, and can continue to process events with time stamps less than or equal to t + delay. The director thread is blocked from processing events with larger time stamps than that because this is necessary to preserve DE semantics. To implement this, this actor uses fireAt() to request a firing at time t + delay, and when that firing occurs, it blocks the director thread until the reaction is complete.

    Parallel firing. Note that if delay is set to 0.0, it may seem that there is no point in using this actor, since model time will not be allowed to increase past t until the contained actor has reacted to events with time stamp t. However, there is actually exploitable concurrency if there are other actors in the model that also have pending input events with time stamp t. Those event can be processed concurrently with this actor reacting to its input event. A typical use case will broadcast an event to several instances of ThreadedComposite, in which case each of those several inside threads can execute concurrently in reaction to those input events.

    Real-time source. If the contained actor (and hence this actor) has no inputs and synchronizeToRealTime is true, then the contained actor must call fireAt() or one of its variants so that the inside thread will be provided with pure events. The behavior depends on which variant of the fireAt() methods is used by the inside actor. There are three cases: FIXME: Described these. In particular, delay needs to specify the minimum increment between these or fireAt() could result in an exception. Do we want a parameter to relax that?

    On subtlety of this actor is that it cannot expose instances of ParameterPort without introducing nondeterminacy in the execution. A ParameterPort is an input port that sets the value of a parameter with the same name. Upon receiving a token at such a port, if this actor were to set a parameter visible by the inside thread, there is no assurance that the inside thread is not still executing an earlier iteration. Thus, it could appear to be sending a message backward in time, which would be truly bizarre. To prevent this error, this actor does not mirror such ports, and hence they appear on the outside only as parameters.

    Since:
    Ptolemy II 8.0
    Version:
    $Id$
    Author:
    Edward A. Lee
    Pt.AcceptedRating:
    Red (eal)
    Pt.ProposedRating:
    Yellow (eal)
    • Field Detail

      • delay

        public Parameter delay
        The model-time delay between the input events and the output events. This is a double that defaults to 0.0, indicating that outputs should have the same time stamps as the inputs that trigger them. If it has a value greater than zero, then the outputs will have larger time stamps by that amount. If it has the value UNDEFINED (or any negative number), then the output time stamp will be nondeterminate, and will depend on the current model time of the outside director when the output is produced or on current real time.
      • synchronizeToRealTime

        public Parameter synchronizeToRealTime
        If set to true, the inside thread stalls until real time matches the time stamps of input events or pure events for each firing. In addition, if delay is set to undefined and this is set to true, then output events are assigned a time stamp that is the greater of current model time and real time. Time is measured since the start of the execution of the inside thread. This is a boolean that defaults to false. Changing the value of this parameter has no effect until the next execution of the model.
    • Constructor Detail

      • ThreadedComposite

        public ThreadedComposite​(CompositeEntity container,
                                 java.lang.String name)
                          throws IllegalActionException,
                                 NameDuplicationException
        Create an actor with a name and a container. The container argument must not be null, or a NullPointerException will be thrown. This actor will use the workspace of the container for synchronization and version counts. If the name argument is null, then the name is set to the empty string. Increment the version of the workspace.
        Parameters:
        container - The container actor.
        name - The name of this actor.
        Throws:
        IllegalActionException - If the container is incompatible with this actor.
        NameDuplicationException - If the name coincides with an actor already in the container.
    • Method Detail

      • attributeChanged

        public void attributeChanged​(Attribute attribute)
                              throws IllegalActionException
        React to a change in an attribute. This method is called by a contained attribute when its value changes. In this base class, the method does nothing. In derived classes, this method may throw an exception, indicating that the new attribute value is invalid. It is up to the caller to restore the attribute to a valid value if an exception is thrown.
        Overrides:
        attributeChanged in class TypedCompositeActor
        Parameters:
        attribute - The attribute that changed.
        Throws:
        IllegalActionException - If the change is not acceptable to this container (not thrown in this base class).
      • clone

        public java.lang.Object clone​(Workspace workspace)
                               throws java.lang.CloneNotSupportedException
        Clone the actor into the specified workspace.
        Overrides:
        clone in class ReflectComposite
        Parameters:
        workspace - The workspace for the new object.
        Returns:
        A new actor.
        Throws:
        java.lang.CloneNotSupportedException - If a derived class has has an attribute that cannot be cloned.
        See Also:
        CompositeEntity.exportMoML(Writer, int, String)
      • getCausalityInterface

        public CausalityInterface getCausalityInterface()
        Override the base class to return a causality interface that indicates that the output does not depend (immediately) on the input. This method assumes that the director deals with BooleanDependencies and returns an instance of BreakCausalityInterface.
        Specified by:
        getCausalityInterface in interface Actor
        Overrides:
        getCausalityInterface in class CompositeActor
        Returns:
        A representation of the dependencies between input ports and output ports.
      • iterateContainedActors

        public boolean iterateContainedActors()
                                       throws IllegalActionException
        Iterate the contained actors of the container of this director.
        Returns:
        False if any contained actor returns false in postfire.
        Throws:
        IllegalActionException - If any called method of of the contained actor throws it, or if the contained actor is not opaque.