ptolemy.domains.dde.kernel
Class DDEReceiver

java.lang.Object
  extended by ptolemy.actor.AbstractReceiver
      extended by ptolemy.domains.dde.kernel.PrioritizedTimedQueue
          extended by ptolemy.domains.dde.kernel.DDEReceiver
All Implemented Interfaces:
ProcessReceiver, Receiver

public class DDEReceiver
extends PrioritizedTimedQueue
implements ProcessReceiver

A DDEReceiver stores time stamped tokens according to distributed discrete event semantics. A time stamped token is a token that has a time stamp associated with it. A DDEReceiver stores time stamped tokens by enforcing a blocking read and blocking write style. Time stamped tokens are appended to the queue with one of the two put() methods, both of which block on a write if the queue is full. Time stamped tokens are removed from the queue via the get() method. The get() method will throw a NoTokenException if it is invoked when the hasToken() method returns false.

Each DDEReceiver is managed by a TimeKeeper. A single time keeper is assigned to manage all of the receivers of a given actor by keeping track of the actor's local notion of time. As tokens are consumed (returned by the get() method) in a receiver, the local time of the actor will advance to the value of the consumed token's time stamp. The hasToken() method of a receiver will return true only if the receiver's get() method will result in the minimum advancement of local time with respect to all of the receivers controlled by the TimeKeeper. If the get() method of multiple receivers will result in a minimum but identical local time advancement, then the hasToken() method of the receiver with the highest priority will return true (the others will return false).

If a receiver with a nonnegative receiver time is empty, then the hasToken() method will perform a blocking read. Once, a token is available then hasToken() will return true or false according to the minimum time advancement rules cited in the preceding paragraph. Note that hasToken() blocks while get() does not block.

DDEReceivers process certain events that are hidden from view by ports and actors. In particular, NullTokens have time stamps with a value of PrioritizedTimedQueue.IGNORE. NullTokens allow actors to communicate information on their local time advancement to neighboring actors without the need for an actual data exchange. NullTokens are passed at the receiver level and circumvent the Ptolemy II data typing mechanism.

Time stamps of value PrioritizedTimedQueue.IGNORE are used to initiate execution in feedback cycles. If a receiver has a time stamp with value IGNORE, then it will not be considered when determining which receiver's get() method will result in the minimum local time advancement. Once a single token has been consumed by any other receiver, then the event with time stamp of value IGNORE will be removed. If all receivers have receiver times of IGNORE, then all such events will be removed.

IMPORTANT: This class assumes that valid time stamps have non-negative values. Reserved negative values exist for special purposes: INACTIVE and IGNORE. These values are attributes of PrioritizedTimedQueue.

Since:
Ptolemy II 0.3
Version:
$Id: DDEReceiver.java 57040 2010-01-27 20:52:32Z cxh $
Author:
John S. Davis II
See Also:
PrioritizedTimedQueue, DDEThread
Accepted Rating:
Green (kienhuis)
Proposed Rating:
Green (davisj)

Field Summary
private  BoundaryDetector _boundaryDetector
          The boundary detector.
private  DDEDirector _director
          The director in charge of this receiver.
private  boolean _hasTokenCache
          Indicator of the result of the most recent call to hasToken().
private  boolean _hideNullTokens
           
private  java.lang.Thread _readPending
          Reference to a thread that is read blocked on this receiver.
private  boolean _terminate
          Flag indicating that termination has been requested.
private  java.lang.Thread _writePending
          Reference to a thread that is write blocked on this receiver.
 
Fields inherited from class ptolemy.domains.dde.kernel.PrioritizedTimedQueue
_lastTime, _priority, ETERNITY, IGNORE, INACTIVE
 
Constructor Summary
DDEReceiver()
          Construct an empty receiver with no container.
DDEReceiver(IOPort container)
          Construct an empty receiver with the specified container.
DDEReceiver(IOPort container, int priority)
          Construct an empty receiver with the specified IOPort container and priority.
 
Method Summary
(package private)  void _hideNullTokens(boolean hide)
          Indicate whether hasToken() should return true if the only available tokens it finds are NullTokens.
 void clear()
          Clear this receiver of any contained tokens.
 Token get()
          Get a token from the mailbox receiver.
 DDEDirector getDirector()
          Return the director in charge of this receiver, or null if there is none.
 boolean hasRoom(int tokens)
          Return true if the receiver has room for putting the given number of tokens into it (via the put() method).
 boolean hasToken()
          Return true if the get() method of this receiver will return a token without throwing a NoTokenException.
 boolean hasToken(int tokens)
          Return true if the receiver contains the given number of tokens that can be obtained by calling the get() method.
 boolean isConnectedToBoundary()
          Return true if this receiver is connected to the inside of a boundary port.
 boolean isConnectedToBoundaryInside()
          Return true if this receiver is connected to the inside of a boundary port.
 boolean isConnectedToBoundaryOutside()
          Return true if this receiver is connected to the outside of a boundary port.
 boolean isConsumerReceiver()
          Return true if this receiver is a consumer receiver.
 boolean isInsideBoundary()
          Return true if this receiver is contained on the inside of a boundary port.
 boolean isOutsideBoundary()
          Return true if this receiver is contained on the outside of a boundary port.
 boolean isProducerReceiver()
          Return true if this receiver is a producer receiver.
 boolean isReadBlocked()
          Return a true or false to indicate whether there is a read block on this receiver or not, respectively.
 boolean isWriteBlocked()
          Return a true or false to indicate whether there is a write block on this receiver or not.
 void put(Token token)
          Do a blocking write on the queue.
 void put(Token token, Time time)
          Do a blocking write on the queue.
 void requestFinish()
          Schedule this receiver to terminate.
 void reset()
          Reset local flags.
 void setContainer(IOPort port)
          Set the container.
 
Methods inherited from class ptolemy.domains.dde.kernel.PrioritizedTimedQueue
_getCompletionTime, _hasNullToken, _setCompletionTime, _setReceiverTime, elementList, getCapacity, getLastTime, getReceiverTime, hasRoom, removeIgnoredToken, setCapacity
 
Methods inherited from class ptolemy.actor.AbstractReceiver
getArray, getContainer, getCurrentTime, getModelTime, isKnown, putArray, putArrayToAll, putToAll, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface ptolemy.actor.Receiver
elementList, getArray, getContainer, hasRoom, isKnown, putArray, putArrayToAll, putToAll
 

Field Detail

_boundaryDetector

private BoundaryDetector _boundaryDetector
The boundary detector.


_director

private DDEDirector _director
The director in charge of this receiver.


_hasTokenCache

private boolean _hasTokenCache
Indicator of the result of the most recent call to hasToken().


_readPending

private java.lang.Thread _readPending
Reference to a thread that is read blocked on this receiver.


_terminate

private boolean _terminate
Flag indicating that termination has been requested.


_writePending

private java.lang.Thread _writePending
Reference to a thread that is write blocked on this receiver.


_hideNullTokens

private boolean _hideNullTokens
Constructor Detail

DDEReceiver

public DDEReceiver()
Construct an empty receiver with no container.


DDEReceiver

public DDEReceiver(IOPort container)
            throws IllegalActionException
Construct an empty receiver with the specified container.

Parameters:
container - The IOPort that contains this receiver.
Throws:
IllegalActionException - If this receiver cannot be contained by the proposed container.

DDEReceiver

public DDEReceiver(IOPort container,
                   int priority)
            throws IllegalActionException
Construct an empty receiver with the specified IOPort container and priority.

Parameters:
container - The IOPort that contains this receiver.
priority - The priority of this receiver.
Throws:
IllegalActionException - If this receiver cannot be contained by the proposed container.
Method Detail

clear

public void clear()
Clear this receiver of any contained tokens.

Specified by:
clear in interface Receiver
Overrides:
clear in class AbstractReceiver

get

public Token get()
Get a token from the mailbox receiver.

Specified by:
get in interface Receiver
Overrides:
get in class PrioritizedTimedQueue
Returns:
The token contained by this receiver.
Throws:
NoTokenException - If there is no token.

getDirector

public DDEDirector getDirector()
Return the director in charge of this receiver, or null if there is none.

Returns:
The director in charge of this receiver.

hasRoom

public boolean hasRoom(int tokens)
Return true if the receiver has room for putting the given number of tokens into it (via the put() method). Returning true in this method should also guarantee that calling the put() method will not result in an exception.

Specified by:
hasRoom in interface Receiver
Overrides:
hasRoom in class PrioritizedTimedQueue
Parameters:
tokens - The number of tokens to put into the queue.
Returns:
True if the queue is not full; return false otherwise.

hasToken

public boolean hasToken()
Return true if the get() method of this receiver will return a token without throwing a NoTokenException. This method will perform a blocking read if this receiver is empty and has a nonnegative receiver time. Once the receiver is no longer empty, this method will return true only if this receiver is sorted first with respect to the other receivers contained by this receiver's actor. The sorting rules are found in ptolemy.domains.dde.kernel.ReceiverComparator.

If at any point during this method this receiver is scheduled for termination, then throw a TerminateProcessException to cease execution of the actor that contains this receiver.

Specified by:
hasToken in interface Receiver
Overrides:
hasToken in class PrioritizedTimedQueue
Returns:
Return true if the get() method of this receiver will return a token without throwing a NoTokenException. Return false if the current thread is not a DDEThread.

hasToken

public boolean hasToken(int tokens)
Return true if the receiver contains the given number of tokens that can be obtained by calling the get() method. Returning true in this method should also guarantee that calling the get() method will not result in an exception.

Specified by:
hasToken in interface Receiver
Overrides:
hasToken in class PrioritizedTimedQueue
Parameters:
tokens - The number of tokens to get from the queue.
Returns:
True if the queue has enough tokens.

isConnectedToBoundary

public boolean isConnectedToBoundary()
                              throws IllegalActionException
Return true if this receiver is connected to the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the inside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundary in interface ProcessReceiver
Returns:
True if this receiver is contained on the inside of a boundary port; return false otherwise.
Throws:
IllegalActionException
See Also:
BoundaryDetector

isConnectedToBoundaryInside

public boolean isConnectedToBoundaryInside()
                                    throws InvalidStateException,
                                           IllegalActionException
Return true if this receiver is connected to the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the inside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundaryInside in interface ProcessReceiver
Returns:
True if this receiver is connected to the inside of a boundary port; return false otherwise.
Throws:
IllegalActionException
InvalidStateException
See Also:
BoundaryDetector

isConnectedToBoundaryOutside

public boolean isConnectedToBoundaryOutside()
                                     throws IllegalActionException
Return true if this receiver is connected to the outside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is connected to the outside of a boundary port, then return true; otherwise return false.

Specified by:
isConnectedToBoundaryOutside in interface ProcessReceiver
Returns:
True if this receiver is connected to the outside of a boundary port; return false otherwise.
Throws:
IllegalActionException
See Also:
BoundaryDetector

isConsumerReceiver

public boolean isConsumerReceiver()
                           throws IllegalActionException
Return true if this receiver is a consumer receiver. A receiver is a consumer receiver if it is connected to a boundary port.

Specified by:
isConsumerReceiver in interface ProcessReceiver
Returns:
True if this is a consumer receiver; return false otherwise.
Throws:
IllegalActionException

isInsideBoundary

public boolean isInsideBoundary()
Return true if this receiver is contained on the inside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is contained on the inside of a boundary port then return true; otherwise return false.

Specified by:
isInsideBoundary in interface ProcessReceiver
Returns:
True if this receiver is contained on the inside of a boundary port; return false otherwise.
See Also:
BoundaryDetector

isOutsideBoundary

public boolean isOutsideBoundary()
Return true if this receiver is contained on the outside of a boundary port. A boundary port is an opaque port that is contained by a composite actor. If this receiver is contained on the outside of a boundary port then return true; otherwise return false.

Specified by:
isOutsideBoundary in interface ProcessReceiver
Returns:
True if this receiver is contained on the outside of a boundary port; return false otherwise.
See Also:
BoundaryDetector

isProducerReceiver

public boolean isProducerReceiver()
Return true if this receiver is a producer receiver. A receiver is a producer receiver if it is contained on the inside or outside of a boundary port.

Specified by:
isProducerReceiver in interface ProcessReceiver
Returns:
True if this is a producer receiver; return false otherwise.

isReadBlocked

public boolean isReadBlocked()
Return a true or false to indicate whether there is a read block on this receiver or not, respectively.

Specified by:
isReadBlocked in interface ProcessReceiver
Returns:
a boolean indicating whether a read is blocked on this receiver or not.

isWriteBlocked

public boolean isWriteBlocked()
Return a true or false to indicate whether there is a write block on this receiver or not.

Specified by:
isWriteBlocked in interface ProcessReceiver
Returns:
A boolean indicating whether a write is blocked on this receiver or not.

put

public void put(Token token)
Do a blocking write on the queue. Set the time stamp to be the current time of the sending actor. If the current time is greater than the completionTime of this receiver, then set the time stamp to INACTIVE and the token to null. If the queue is full, then inform the director that this receiver is blocking on a write and wait until room becomes available. When room becomes available, put the token and time stamp in the queue and inform the director that the block no longer exists. If at any point during this method this receiver is scheduled for termination, then throw a TerminateProcessException which will cease activity for the actor that contains this receiver.

Specified by:
put in interface Receiver
Overrides:
put in class PrioritizedTimedQueue
Parameters:
token - The token to put in the queue, or null to put no token.
Throws:
TerminateProcessException - If activity is scheduled to cease.

put

public void put(Token token,
                Time time)
Do a blocking write on the queue. Set the time stamp to be the time specified by the time parameter. If the specified time is greater than the completionTime of this receiver, then set the time stamp to INACTIVE and the token to null. If the queue is full, then inform the director that this receiver is blocking on a write and wait until room becomes available. When room becomes available, put the token and time stamp in the queue and inform the director that the block no longer exists. If at any point during this method this receiver is scheduled for termination, then throw a TerminateProcessException which will cease activity for the actor that contains this receiver.

Overrides:
put in class PrioritizedTimedQueue
Parameters:
token - The token to put in the queue, or null to put no token.
time - The specified time stamp.
Throws:
TerminateProcessException - If activity is scheduled to cease.

requestFinish

public void requestFinish()
Schedule this receiver to terminate. After this method is called, a TerminateProcessException will be thrown during the next call to get() or put() of this class.

Specified by:
requestFinish in interface ProcessReceiver

reset

public void reset()
Reset local flags. The local flag of this receiver indicates whether this receiver is scheduled for termination. Resetting the termination flag will make sure that this receiver is not scheduled for termination.

Specified by:
reset in interface ProcessReceiver
Specified by:
reset in interface Receiver
Overrides:
reset in class PrioritizedTimedQueue

setContainer

public void setContainer(IOPort port)
                  throws IllegalActionException
Set the container. This overrides the base class to record the director.

Specified by:
setContainer in interface Receiver
Overrides:
setContainer in class AbstractReceiver
Parameters:
port - The container.
Throws:
IllegalActionException - If the container is not of an appropriate subclass of IOPort, or if the container's director is not an instance of DDEDirector.
See Also:
AbstractReceiver.getContainer()

_hideNullTokens

void _hideNullTokens(boolean hide)
Indicate whether hasToken() should return true if the only available tokens it finds are NullTokens. Specify that NullTokens should not be taken into consideration by hasToken() if the parameter is true; otherwise do consider NullTokens. This method is used in special circumstances in NullTokens must be manipulated at the actor level. In particular, FeedBackDelay uses this method so that it can "see" NullTokens that it receives and give them appropriate delay values. For this reason this method is package friendly.

Parameters:
hide - The parameter indicating whether NullTokens should be taken into consideration by hasToken().