Class PNDirector

  • All Implemented Interfaces:
    java.lang.Cloneable, Executable, Initializable, Changeable, Debuggable, DebugListener, Derivable, ModelErrorHandler, MoMLExportable, Moveable, Nameable
    Direct Known Subclasses:
    MetroIIPNDirector, TimedPNDirector

    public class PNDirector
    extends CompositeProcessDirector

    A PNDirector governs the execution of a CompositeActor with extended Kahn-MacQueen process networks (PN) semantics. This model of computation has been extended to support mutations of graphs in a non-deterministic way.

    The thread that calls the various execution methods (initialize, prefire, fire and postfire) on the director is referred to as the directing thread. This directing thread might be the main thread responsible for the execution of the entire simulation or might be the thread created by the executive director of the containing composite actor.

    In the PN domain, the director creates a thread (an instance of ProcessThread), representing a Kahn process, for each actor in the model. The threads are created in initialize() and started in the prefire() method of the ProcessDirector. A process is considered active from its creation until its termination. An active process can block when trying to read from a channel (read-blocked), when trying to write to a channel (write-blocked) or when waiting for a queued topology change request to be processed (mutation-blocked).

    A deadlock is when all the active processes are blocked. The director is responsible for handling deadlocks during execution. This director handles two different sorts of deadlocks, real deadlock and artificial deadlock.

    A real deadlock is when all the processes are blocked on a read meaning that no process can proceed until it receives new data. The execution can be terminated, if desired, in such a situation. If the container of this director does not have any input ports (as is in the case of a top-level composite actor), then the executive director or manager terminates the execution. If the container has input ports, then it is up to the executive director of the container to decide on the termination of the execution. To terminate the execution after detection of a real deadlock, the manager or the executive director calls wrapup() on the director.

    An artificial deadlock is when all processes are blocked and at least one process is blocked on a write. In this case the director increases the capacity of the receiver with the smallest capacity amongst all the receivers on which a process is blocked on a write. This breaks the deadlock and the execution can resume. If the increase results in a capacity that exceeds the value of maximumQueueCapacity, then instead of breaking the deadlock, an exception is thrown. This can be used to detect erroneous models that require unbounded queues.

    There are at least three ways for a PN model to terminate itself:

    1. Have the model starve itself. Typically, a boolean switch is used. See the PN OrderedMerge demo at ptolemy/domains/pn/demo/OrderedMerge/OrderedMerge.xml
    2. Have the model call the Stop actor. See the PN RemoveNilTokens demo at ptolemy/domains/pn/demo/RemoveNilTokens/RemoveNilTokens.xmll
    3. Set the firingCountLimit (LimitedFiringSource._firingCountLimit) actor parameter to the number of iterations desired. Actors such as Ramp extend LimitedFiringSource and have the firingCountLimit parameter.
    Since:
    Ptolemy II 0.2
    Version:
    $Id$
    Author:
    Mudit Goel, Edward A. Lee, Xiaowen Xin
    Pt.AcceptedRating:
    Green (davisj)
    Pt.ProposedRating:
    Green (mudit)
    • Field Detail

      • initialQueueCapacity

        public Parameter initialQueueCapacity
        The initial size of the queues for each communication channel. This is an integer that defaults to 1.
      • maximumQueueCapacity

        public Parameter maximumQueueCapacity
        The maximum size of the queues for each communication channel. This is an integer that defaults to 65536. To specify unbounded queues, set this to 0.
      • READ_BLOCKED

        public static final boolean READ_BLOCKED
        Indicator that a thread is read blocked.
        See Also:
        Constant Field Values
      • WRITE_BLOCKED

        public static final boolean WRITE_BLOCKED
        Indicator that a thread is write blocked.
        See Also:
        Constant Field Values
      • _readBlockedQueues

        protected java.util.HashMap _readBlockedQueues
        The set of processes blocked on a read from a receiver.
      • _writeBlockedQueues

        protected java.util.HashMap _writeBlockedQueues
        The set of receivers blocked on a write to a receiver.
      • _receivers

        protected java.util.LinkedList _receivers
        The list of all receivers that this director has created.
    • Constructor Detail

      • PNDirector

        public PNDirector()
                   throws IllegalActionException,
                          NameDuplicationException
        Construct a director in the default workspace with an empty string as its name. The director is added to the list of objects in the workspace. Increment the version number of the workspace. Create a director parameter "initialQueueCapacity" with the default value 1. This sets the initial capacities of the queues in all the receivers created in the PN domain.
        Throws:
        IllegalActionException - If the name has a period in it, or the director is not compatible with the specified container.
        NameDuplicationException - If the container already contains an entity with the specified name.
      • PNDirector

        public PNDirector​(Workspace workspace)
                   throws IllegalActionException,
                          NameDuplicationException
        Construct a director in the workspace with an empty name. The director is added to the list of objects in the workspace. Increment the version number of the workspace. Create a director parameter "initialQueueCapacity" with the default value 1. This sets the initial capacities of the queues in all the receivers created in the PN domain.
        Parameters:
        workspace - The workspace of this object.
        Throws:
        IllegalActionException - If the name has a period in it, or the director is not compatible with the specified container.
        NameDuplicationException - If the container already contains an entity with the specified name.
      • PNDirector

        public PNDirector​(CompositeEntity container,
                          java.lang.String name)
                   throws IllegalActionException,
                          NameDuplicationException
        Construct a director in the given container with the given name. If the container argument must not be null, or a NullPointerException will be thrown. If the name argument is null, then the name is set to the empty string. Increment the version number of the workspace. Create a director parameter "initialQueueCapacity" with the default value 1. This sets the initial capacities of the queues in all the receivers created in the PN domain.
        Parameters:
        container - Container of the director.
        name - Name of this director.
        Throws:
        IllegalActionException - If the director is not compatible with the specified container. Thrown in derived classes.
        NameDuplicationException - If the container not a CompositeActor and the name collides with an entity in the container.
    • Method Detail

      • addProcessListener

        public void addProcessListener​(PNProcessListener listener)
        Add a process state change listener to this director. The listener will be notified of each change to the state of a process.
        Parameters:
        listener - The PNProcessListener to add.
        See Also:
        removeProcessListener(PNProcessListener)
      • clone

        public java.lang.Object clone​(Workspace workspace)
                               throws java.lang.CloneNotSupportedException
        Clone the director into the specified workspace. The new object is not added to the directory of that workspace (It must be added by the user if he wants it to be there). The result is a new director with no container, no pending mutations, and no topology listeners. The count of active processes is zero.
        Overrides:
        clone in class CompositeProcessDirector
        Parameters:
        workspace - The workspace for the cloned object.
        Returns:
        The new PNDirector.
        Throws:
        java.lang.CloneNotSupportedException - If one of the attributes cannot be cloned.
        See Also:
        NamedObj.exportMoML(Writer, int, String), NamedObj.setDeferringChangeRequests(boolean)
      • initialize

        public void initialize()
                        throws IllegalActionException
        Invoke the initialize() method of ProcessDirector. Also set all the state variables to the their initial values. The list of process listeners is not reset as the developer might want to reuse the list of listeners.
        Specified by:
        initialize in interface Initializable
        Overrides:
        initialize in class CompositeProcessDirector
        Throws:
        IllegalActionException - If the initialize() method of one of the deeply contained actors throws it.
      • newReceiver

        public Receiver newReceiver()
        Return a new receiver compatible with this director. The receiver is an instance of PNQueueReceiver. Set the initial capacity of the FIFO queue in the receiver to the value specified by the director parameter "initialQueueCapacity". The default value of the parameter is 1.
        Overrides:
        newReceiver in class CompositeProcessDirector
        Returns:
        A new PNQueueReceiver.
      • postfire

        public boolean postfire()
                         throws IllegalActionException
        Return true if the containing composite actor contains active processes and the composite actor has input ports and if stop() has not been called. Return false otherwise. This method is normally called only after detecting a real deadlock, or if stopFire() is called. True is returned to indicate that the composite actor can start its execution again if it receives data on any of its input ports.
        Specified by:
        postfire in interface Executable
        Overrides:
        postfire in class ProcessDirector
        Returns:
        true to indicate that the composite actor can continue executing on receiving additional input on its input ports.
        Throws:
        IllegalActionException - Not thrown in this base class. May be thrown by derived classes.
      • removeProcessListener

        public void removeProcessListener​(PNProcessListener listener)
        Remove a process listener from this director. If the listener is not attached to this director, do nothing.
        Parameters:
        listener - The PNProcessListener to be removed.
        See Also:
        addProcessListener(PNProcessListener)
      • suggestedModalModelDirectors

        public java.lang.String[] suggestedModalModelDirectors()
        Return an array of suggested ModalModel directors to use with PNDirector. The default director is MultirateFSMDirector, the alternative director is FSMDirector.
        Overrides:
        suggestedModalModelDirectors in class Director
        Returns:
        An array of suggested directors to be used with ModalModel.
        See Also:
        Director.suggestedModalModelDirectors()
      • supportMultirateFiring

        public boolean supportMultirateFiring()
        Return true to indicate that a ModalModel under control of this director supports multirate firing.
        Overrides:
        supportMultirateFiring in class Director
        Returns:
        True indicating a ModalModel under control of this director supports multirate firing.
      • threadBlocked

        public void threadBlocked​(java.lang.Thread thread,
                                  ProcessReceiver receiver,
                                  boolean readOrWrite)
        Notify the director that the specified thread is blocked on an I/O operation.
        Parameters:
        thread - The thread.
        receiver - The receiver handling the I/O operation, or null if it is not a specific receiver.
        readOrWrite - Either READ_BLOCKED or WRITE_BLOCKED to indicate whether the thread is blocked on read or write.
        See Also:
        CompositeProcessDirector.threadBlocked(Thread, ProcessReceiver)
      • threadUnblocked

        public void threadUnblocked​(java.lang.Thread thread,
                                    ProcessReceiver receiver,
                                    boolean readOrWrite)
        Notify the director that the specified thread is unblocked on an I/O operation. If the thread has not been registered with threadBlocked(), then this call is ignored.
        Parameters:
        thread - The thread.
        receiver - The receiver handling the I/O operation, or null if it is not a specific receiver.
        readOrWrite - Either READ_BLOCKED or WRITE_BLOCKED to indicate whether the thread is blocked on read or write.
        See Also:
        CompositeProcessDirector.threadUnblocked(Thread, ProcessReceiver)
      • _incrementLowestWriteCapacityPort

        protected void _incrementLowestWriteCapacityPort()
                                                  throws IllegalActionException
        Double the capacity of one of the queues with the smallest capacity belonging to a receiver on which a process is blocked while attempting to write.

        Traverse through the list of receivers on which a process is blocked on a write and choose the one containing the queue with the smallest capacity. Double the capacity if the capacity is non-negative. In case the capacity is negative, set the capacity to 1. Unblock the process blocked on a write to the receiver containing this queue. Notify the thread corresponding to the blocked process to resume its execution and return.

        Throws:
        IllegalActionException - If the resulting capacity would exceed the value of maximumQueueCapacity.
      • _resolveInternalDeadlock

        protected boolean _resolveInternalDeadlock()
                                            throws IllegalActionException
        Resolve an artificial deadlock and return true. If the deadlock is not an artificial deadlock (it is a real deadlock), then return false. If it is an artificial deadlock, select the receiver with the smallest queue capacity on which any process is blocked on a write and increment the capacity of the contained queue. If the capacity is non-negative, then increment the capacity by 1. Otherwise set the capacity to 1. Unblock the process blocked on this receiver. Notify the thread corresponding to the blocked process and return true.

        If derived classes introduce new forms of deadlocks, they should override this method to introduce mechanisms of handling those deadlocks. This method is called from the fire() method of the director alone.

        Overrides:
        _resolveInternalDeadlock in class CompositeProcessDirector
        Returns:
        True after handling an artificial deadlock. Otherwise return false.
        Throws:
        IllegalActionException - If the maximum queue capacity is exceeded. This might be thrown by derived classes.