ptolemy.domains.csp.kernel
Class ConditionalSend

java.lang.Object
  extended by ptolemy.domains.csp.kernel.ConditionalBranch
      extended by ptolemy.domains.csp.kernel.ConditionalSend
All Implemented Interfaces:
java.lang.Runnable, Debuggable

public class ConditionalSend
extends ConditionalBranch
implements java.lang.Runnable

Represents a guarded communication statement in which the communication is a send(). Thus is represents

guard; send() => statements

It is one branch of either a CDO or a CIF conditional communication construct.

The branches used in a conditional communication construct are controlled by the chooseBranch() method of ConditionalBranchController.

Each branch is created to perform one communication. If more than one branch is enabled (the guard is true or absent), then a thread is created for each enabled branch to try and perform the appropriate rendezvous. If the branch succeeds and is allowed to rendezvous, then it registers itself with the controller and the thread it is running in dies. Otherwise it continues to try and rendezvous until it succeeds or it is notified that another branch has succeeded in with its rendezvous, in which case this branch has failed and the thread it is running in dies.

For rendezvous, the receiver is the key synchronization point. The receiver with which this branch will try to rendezvous is set upon instantiation. It is determined from the port and channel which is passed in in the constructor.

The algorithm by which a branch determines whether or not it has succeeded with its rendezvous is executed in the run method. There are roughly three parts to the algorithm, each of which is relevant to the different rendezvous scenarios.
Case 1: There is a get already waiting at the rendezvous point. In this case the branch attempts to register itself, with the controller, as the first branch ready to rendezvous. If it succeeds, it performs the rendezvous, notifies the controller that it succeeded and returns. If it is not the first, it keeps on trying to register itself until it finally succeeds or another branch succeeds with a rendezvous in which case it fails and terminates. Note that a put cannot "go away" so it remains in an inner-loop trying to rendezvous or failing.
Case 2: There is a conditional receive waiting. In this case it tries to register both branches with their controllers as the first to try. If it succeeds it performs the transfer, notifies the controller and returns. It performs the registration in two steps, first registering this branch and then registering the other branch. If it successfully registers this branch, but cannot register the other, it unregisters itself as the first branch trying, and starts trying to rendezvous from the beginning. This is because the conditional send could "go away". If it is unable to register itself as the first branch to try, it again starts trying to rendezvous from the beginning.
Case 3: If there is neither a get or a conditional receive waiting, it sets a flag in the receiver that a conditional send is trying to rendezvous. It then waits until a get is executed on the receiver, or until another branch succeeds and this branch fails. If this branch fails, it resets the flag in the receiver, notifies the controller and returns. Note that it only needs to wait on a get as if a conditional receive is executed on the receiver, it is the branch which is responsible for checking that the rendezvous can proceed. Thus, in the case where two conditional branches are trying to rendezvous at a receiver, it is the responsibility of the branch arriving second to check that the rendezvous can proceed(see case 2).

Since:
Ptolemy II 0.2
Version:
$Id: ConditionalSend.java 57040 2010-01-27 20:52:32Z cxh $
Author:
Neil Smyth and Edward A. Lee
See Also:
ConditionalBranch
Accepted Rating:
Red (eal)

Proposed Rating:
Green (eal)

Field Summary
private  int _channel
          The channel on which we are sending.
private  IOPort _port
          The port from which we are sending.
 
Fields inherited from class ptolemy.domains.csp.kernel.ConditionalBranch
_debugging, _guard
 
Constructor Summary
ConditionalSend(boolean guard, IOPort port, int channel, int branchID, Token token)
          Create a guarded communication with a send communication.
ConditionalSend(boolean guard, IOPort port, int channel, int branchID, Token token, ConditionalBranchController controller)
          Create a guarded communication with a send communication.
ConditionalSend(IOPort port, int channel, int branchID, Token token)
          Create a conditional send.
 
Method Summary
protected  boolean _isGetOrConditionalReceiveWaitingOnAll(Receiver[] receivers)
          Return whether all specified receivers have either a conditional receive waiting or a get waiting.
protected  boolean _isGetWaitingOnAll(Receiver[] receivers)
          Return whether a get() is waiting to rendezvous at all the specified receivers.
protected  boolean _isReady()
          Return true if this conditional branch is ready to rendezvous.
 void run()
          The run method has roughly three parts: (1) when there is already a get waiting, (2) when there is a ConditionalReceive waiting, and (3) where this ConditionalSend is the first to arrive at the receiver.
 
Methods inherited from class ptolemy.domains.csp.kernel.ConditionalBranch
_debug, _setAlive, _setReceivers, _setToken, addDebugListener, getController, getGuard, getID, getPort, getReceivers, getToken, isAlive, removeDebugListener
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_channel

private int _channel
The channel on which we are sending.


_port

private IOPort _port
The port from which we are sending.

Constructor Detail

ConditionalSend

public ConditionalSend(IOPort port,
                       int channel,
                       int branchID,
                       Token token)
                throws IllegalActionException
Create a conditional send.

Parameters:
port - The IOPort containing the channel (and thus receiver) that this branch will try to rendezvous with.
channel - The channel in the IOPort that this branch is trying to rendezvous with.
branchID - The identification number assigned to this branch upon creation by the CSPActor.
token - The token this branch is trying to send.
Throws:
IllegalActionException - If the channel has more than one receiver or if the receiver is not of type CSPReceiver.

ConditionalSend

public ConditionalSend(boolean guard,
                       IOPort port,
                       int channel,
                       int branchID,
                       Token token)
                throws IllegalActionException
Create a guarded communication with a send communication.

Parameters:
guard - The guard for the guarded communication statement represented by this object.
port - The IOPort containing the channel (and thus receiver) that this branch will try to rendezvous with.
channel - The channel in the IOPort that this branch is trying to rendezvous with.
branchID - The identification number assigned to this branch upon creation by the CSPActor.
token - The token this branch is trying to send.
Throws:
IllegalActionException - If the channel has more than one receiver or if the receiver is not of type CSPReceiver.

ConditionalSend

public ConditionalSend(boolean guard,
                       IOPort port,
                       int channel,
                       int branchID,
                       Token token,
                       ConditionalBranchController controller)
                throws IllegalActionException
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.

Parameters:
guard - The guard for the guarded communication statement represented by this object.
port - The IOPort containing the channel (and thus receiver) that this branch will try to rendezvous with.
channel - The channel in the IOPort that this branch is trying to rendezvous with.
branchID - The identification number assigned to this branch upon creation by the CSPActor.
token - The token this branch is trying to send.
controller - The controller that this branch uses.
Throws:
IllegalActionException - If the channel has more than one receiver or if the receiver is not of type CSPReceiver.
Method Detail

run

public void run()
The run method has roughly three parts: (1) when there is already a get waiting, (2) when there is a ConditionalReceive waiting, and (3) where this ConditionalSend is the first to arrive at the receiver.

The algorithm used in this method, together with some methods in ConditionalBranchController, control how conditional communication takes place in the CSP domain.

Specified by:
run in interface java.lang.Runnable

_isGetOrConditionalReceiveWaitingOnAll

protected boolean _isGetOrConditionalReceiveWaitingOnAll(Receiver[] receivers)
Return whether all specified receivers have either a conditional receive waiting or a get waiting.

Parameters:
receivers - The receivers to check.
Returns:
True all specified receivers have either a conditional receive or a get waiting.

_isGetWaitingOnAll

protected boolean _isGetWaitingOnAll(Receiver[] receivers)
Return whether a get() is waiting to rendezvous at all the specified receivers.

Parameters:
receivers - The receivers to check.
Returns:
True if a get() is waiting to rendezvous.

_isReady

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

Specified by:
_isReady in class ConditionalBranch
Returns:
True if the associated receivers all have either a pending conditional receive or a get waiting.