ptolemy.domains.csp.kernel
Class ConditionalBranch

java.lang.Object
  extended by ptolemy.domains.csp.kernel.ConditionalBranch
All Implemented Interfaces:
Debuggable
Direct Known Subclasses:
ConditionalReceive, ConditionalSend

public abstract class ConditionalBranch
extends java.lang.Object
implements Debuggable

Base class for classes representing guarded communication that occurs either conditionally (one statement from a group is executed) or as a multiway rendezvous (all statements from a group are executed). Concrete subclasses are expected to implement the Runnable interface, and the "execution" of the communication is in the run() method. A guarded communication statement is of the form

guard; communication => statements

If the guard is true, or absent which implies true, then the branch is enabled. If a branch is not enabled, then this it does not participate in the group (equivalently, it could not be created or put in the group). A group is formed and executed by calling chooseBranch() in a ConditionalBranchController or MultiwayBranchController.

Guarded communication statements of the conditional sort are used to perform two forms of conditional communication constructs from classical CSP: "conditional if" (CIF) and "conditional do" (CDO). These constructs are analogous to, but different from, the common if and do statements. Each guarded communication statement is one branch of a CIF or CDO.

A CDO has the form

CDO {
G1; C1 => S1;
[]
G2; C2 => S2;
[]
...
}

The G1, G2 etc. represent the guards. The C1, C2 etc. represent the communication associated with that branch, and may be either a send() or a get(). The S1, S2 etc. represent the blocks of statements associated with that branch. They are executed if that branch is successful. The "[]" hints at the fact that the guards are all evaluated in parallel (as opposed to sequentially in a common if statement).

While at least one of the branches is enabled, the construct continues to evaluate and execute one of the enabled branches. If more than one branch is enabled, the first branch to be able to rendezvous succeeds and its statements are executed. Note that this construct is nondeterministic as it may be a race condition that determines which branch is successful. The CIF is similar to the CDO except that it is only evaluated once.

The communication part of a guarded communication statement can be either a send() or a get(). There are thus two subclasses of this class, each representing a guarded communication statement for one of the communication primitives. The subclasses are ConditionalSend and ConditionalReceive.

If more than one branch is enabled, each enabled branch is executed in a separate thread.

Conditional branches are designed to be used once. Upon instantiation, they are given the guard, the port and channel over which to communicate, and the identification number of the branch according to the controller. The port and the channel together define the CSPReceiver with which to rendezvous. The ConditionalBranchController, that controls this branch, is assumed to be contained by the container of the port.

Since:
Ptolemy II 0.2
Version:
$Id: ConditionalBranch.java 57040 2010-01-27 20:52:32Z cxh $
Author:
Neil Smyth and Edward A. Lee
Accepted Rating:
Green (kienhuis)
Proposed Rating:
Green (nsmyth)

Field Summary
private  boolean _alive
          Has another branch successfully rendezvoused?
private  int _branchID
          The identification number of this branch (according to its controller).
private  AbstractBranchController _controller
          The controller of this thread is trying to perform a conditional rendezvous for.
protected  boolean _debugging
          Flag that is true if there are debug listeners.
private  java.util.LinkedList _debugListeners
          The list of DebugListeners registered with this object.
protected  boolean _guard
          The guard for this guarded communication statement.
private  IOPort _port
          The port specified in the constructor.
private  Receiver[] _receivers
          The receivers that this thread is trying to rendezvous with.
private  Token _token
          The Token transferred in a rendezvous.
 
Constructor Summary
ConditionalBranch(boolean guard, IOPort port, int branchID)
          Create a guarded communication statement.
ConditionalBranch(boolean guard, IOPort port, int branchID, ConditionalBranchController controller)
          Create a guarded communication statement.
 
Method Summary
protected  void _debug(java.lang.String message)
          Send a debug message to all debug listeners that have registered.
protected abstract  boolean _isReady()
          Return true if this conditional branch is ready to rendezvous.
protected  void _setAlive(boolean value)
          Set a flag indicating this branch should fail.
protected  void _setReceivers(Receiver[] receivers)
          Set the receivers that this branch is trying to rendezvous with.
protected  void _setToken(Token token)
          Set the token contained by this branch.
 void addDebugListener(DebugListener listener)
          Add a debug listener.
 AbstractBranchController getController()
          Return the controller that manges conditional rendezvous for this branch when performing a CIF or CDO.
 boolean getGuard()
          Returns the guard for this guarded communication statement.
 int getID()
          Returns the identification number of this branch(according to its controller).
 IOPort getPort()
          Return the port associated with this conditional branch.
 Receiver[] getReceivers()
          Return an array with all the receivers that this branch is trying to rendezvous with.
 Token getToken()
          Return the token contained by this branch.
 boolean isAlive()
          Boolean indicating if this branch is still alive.
 void removeDebugListener(DebugListener listener)
          Unregister a debug listener.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_debugging

protected boolean _debugging
Flag that is true if there are debug listeners.


_guard

protected boolean _guard
The guard for this guarded communication statement.


_alive

private boolean _alive
Has another branch successfully rendezvoused? If so, then _alive is set to false. Otherwise, this branch still can potentially rendezvous. _alive remains true until it is no longer possible for this branch to successfully rendezvous.


_branchID

private int _branchID
The identification number of this branch (according to its controller).


_controller

private AbstractBranchController _controller
The controller of this thread is trying to perform a conditional rendezvous for.


_debugListeners

private java.util.LinkedList _debugListeners
The list of DebugListeners registered with this object.


_port

private IOPort _port
The port specified in the constructor.


_receivers

private Receiver[] _receivers
The receivers that this thread is trying to rendezvous with.


_token

private Token _token
The Token transferred in a rendezvous.

Constructor Detail

ConditionalBranch

public ConditionalBranch(boolean guard,
                         IOPort port,
                         int branchID)
                  throws IllegalActionException
Create a guarded communication statement. This class contains all of the information necessary to carry out a guarded communication statement, with the exception of the type of communication. The receiver is set in the subclass as it is subject to communication specific tests.

Parameters:
guard - The guard for the guarded communication statement represented by this object.
port - The IOPort that contains the channel to try an communicate through.
branchID - The identification number assigned to this branch upon creation by the CSPActor.
Throws:
IllegalActionException - If the actor that contains the port is not of type CSPActor.

ConditionalBranch

public ConditionalBranch(boolean guard,
                         IOPort port,
                         int branchID,
                         ConditionalBranchController controller)
                  throws IllegalActionException
Create a guarded communication statement. This class contains all of the information necessary to carry out a guarded communication statement, with the exception of the type of communication. The receiver is set in the subclass as it is subject to communication specific tests. This constructor allows actors which do not implement the BranchActor interface access to CSP functionality by passing their own ConditionalBranchController.

Parameters:
guard - The guard for the guarded communication statement represented by this object.
port - The IOPort that contains the channel to try an communicate through.
branchID - The identification number assigned to this branch upon creation by the CSPActor.
controller - The controller associated with this branch, or null to use the one provided by the container of the port.
Throws:
IllegalActionException - If the actor that contains the port is not of type CSPActor, or if no controller is provided, and the actor is not an instance of BranchActor.
Method Detail

addDebugListener

public void addDebugListener(DebugListener listener)
Add a debug listener. If the listener is already in the list, do not add it again.

Specified by:
addDebugListener in interface Debuggable
Parameters:
listener - The listener to which to send debug messages.
See Also:
removeDebugListener(DebugListener)

getGuard

public boolean getGuard()
Returns the guard for this guarded communication statement. If it is true the branch is said to be enabled.

Returns:
True if the branch is enabled.

getID

public int getID()
Returns the identification number of this branch(according to its controller).

Returns:
The identification number of this branch.

getController

public AbstractBranchController getController()
Return the controller that manges conditional rendezvous for this branch when performing a CIF or CDO.

Returns:
The controller that manages conditional rendezvous for this branch.

getPort

public IOPort getPort()
Return the port associated with this conditional branch.

Returns:
The port specified in the constructor.

getReceivers

public Receiver[] getReceivers()
Return an array with all the receivers that this branch is trying to rendezvous with. In this base class, this is an array with one element, the receiver returned by getReceiver(). However, in the ConditionalSend derived class, the array may contain more than one receiver.

Returns:
An array of receivers that this branch is trying to rendezvous with.

getToken

public Token getToken()
Return the token contained by this branch. For a ConditionalSend it is set upon creation, and set to null after the rendezvous. For a ConditionalReceive it is set after the rendezvous has occurred, and is null before that.

Returns:
The token contained by this branch.

isAlive

public boolean isAlive()
Boolean indicating if this branch is still alive. If it is false, it indicates another conditional branch was able to rendezvous before this branch, and this branch should stop trying to rendezvous with its receiver and terminate. If it is true, the branch should continue trying to rendezvous.

Returns:
True if this branch is still alive.

removeDebugListener

public void removeDebugListener(DebugListener listener)
Unregister a debug listener. If the specified listener has not been previously registered, then do nothing.

Specified by:
removeDebugListener in interface Debuggable
Parameters:
listener - The listener to remove from the list of listeners to which debug messages are sent.
See Also:
addDebugListener(DebugListener)

_setAlive

protected void _setAlive(boolean value)
Set a flag indicating this branch should fail.

Parameters:
value - Boolean indicating whether this branch is still alive.

_setReceivers

protected void _setReceivers(Receiver[] receivers)
Set the receivers that this branch is trying to rendezvous with. This method should only be called from derived classes. For a conditional receiver, the argument should be an array with only one receiver. For a conditional send, the argument may have more than one receiver, in which case a multi-way rendezvous is being specified.

Parameters:
receivers - The instances of CSPReceiver that this branch is trying to rendezvous with.

_setToken

protected void _setToken(Token token)
Set the token contained by this branch. For a ConditionalSend it is set upon creation, and set to null after the rendezvous. For a ConditionalReceive it is set after the rendezvous has occurred, and is null before that.

Parameters:
token - The token to be contained by this branch.

_debug

protected final void _debug(java.lang.String message)
Send a debug message to all debug listeners that have registered. By convention, messages should not include a newline at the end. The newline will be added by the listener, if appropriate.

Parameters:
message - The message.

_isReady

protected abstract boolean _isReady()
Return true if this conditional branch is ready to rendezvous.

Returns:
True if the conditional branch is ready to rendezvous.