/* A CSP actor that creates an output only after timed deadlock
has been reached by all other CSP actors in the containing
composite actor.
Copyright (c) 1998-2005 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the above
copyright notice and the following two paragraphs appear in all copies
of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY
*/
package ptolemy.domains.csp.demo.BusContention;
// Ptolemy imports.
import ptolemy.actor.TypedIOPort;
import ptolemy.data.Token;
import ptolemy.data.type.BaseType;
import ptolemy.domains.csp.kernel.CSPActor;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
//////////////////////////////////////////////////////////////////////////
//// ContentionAlarm
/**
A ContentionAlarm is a CSP actor that creates an output only after
timed deadlock has been reached by all other CSP actors in the
containing composite actor. A ContentionAlarm has one input and
one output port as well as three "informal" states. During the
fire() method, the actor is enabled to cycle through each of the
three states.
In state one, the ContentionAlarm attempts to receive a token through
its input port. Once a token has been received, the actor enters state
two and calls the _waitForDeadlock() method that it inherits from
CSPActor. This method means that the actor becomes time delayed and
will not continue until all other actors in the composite actor are
either blocked or time delayed. Once _waitForDeadlock() returns, the
actor enters state three and sends a token through its output port.
A useful application of ContentionAlarm is to notify other actors
if there are multiple contenders for a given resource at a given
time. Because of the semantics of _waitForDeadlock(), ContentionAlarm
will not "wake up" until all contenders have attempted to access a
particular resource.
In addition to the time delay oriented semantics of ContentionAlarm,
it can also notify an ExecEventListener as this actor jumps between
its three states. Such notification is enabled by adding an
ExecEventListener to this actor's listener list via the addListeners()
method. Listeners can be removed via the removeListeners() method.
ExecEventListeners are currently implemented to serve as conduits
between Ptolemy II and the Diva graphical user interface.
@author John S. Davis II
@version $Id$
@since Ptolemy II 0.3
@Pt.ProposedRating Red (davisj)
@Pt.AcceptedRating Red (cxh)
@see ptolemy.actor.gui.ExecEvent
@see ptolemy.actor.gui.ExecEventListener
*/
public class ContentionAlarm extends CSPActor {
/** Construct a ContentionAlarm actor with the specified container
* and name. Set the type of the input and ouput ports to
* BaseType.GENERAL.
* @param cont The container of this actor.
* @param name The name of this actor.
* @exception IllegalActionException If the actor cannot be
* contained by the proposed container.
* @exception NameDuplicationException If the container
* already has an actor with this name.
*/
public ContentionAlarm(CompositeEntity cont, String name)
throws IllegalActionException, NameDuplicationException {
super(cont, name);
input = new TypedIOPort(this, "input", true, false);
output = new TypedIOPort(this, "output", false, true);
input.setTypeEquals(BaseType.GENERAL);
output.setTypeEquals(BaseType.GENERAL);
}
///////////////////////////////////////////////////////////////////
//// ports and parameters ////
/** The input port. The type of this port is BaseType.GENERAL.
*/
public TypedIOPort input;
/** The output port. The type of this port is BaseType.GENERAL.
*/
public TypedIOPort output;
///////////////////////////////////////////////////////////////////
//// public methods ////
/** Execute this actor by cycling through its three states
* continually. Each state can potentially block due to
* the blocking semantics of CSP communication. Upon entry
* into each state, generate an ExecEvent with the
* corresponding state value.
* @exception IllegalActionException If communication through
* the input or output ports throws an IllegalActionException.
*/
public void fire() throws IllegalActionException {
super.fire();
while (true) {
// State 1
_debug(new ExecEvent(this, ExecEvent.WAITING));
input.get(0);
// State 2
_debug(new ExecEvent(this, ExecEvent.WAITING));
_waitForDeadlock();
// State 3
_debug(new ExecEvent(this, ExecEvent.ACCESSING));
output.send(0, new Token());
}
}
}