Package ptolemy.domains.csp.demo.BusContention

Source Code of ptolemy.domains.csp.demo.BusContention.Controller

/* A CSP actor that serves as a controller of a shared resource.

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;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import ptolemy.actor.Receiver;
import ptolemy.actor.TypedIOPort;
import ptolemy.data.BooleanToken;
import ptolemy.data.IntToken;
import ptolemy.data.Token;
import ptolemy.data.type.BaseType;
import ptolemy.domains.csp.kernel.CSPActor;
import ptolemy.domains.csp.kernel.ConditionalBranch;
import ptolemy.domains.csp.kernel.ConditionalReceive;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;

//////////////////////////////////////////////////////////////////////////
//// Controller

/**
A CSP actor that serves as a controller of a shared resource. This
actor has four "informal" states that are cycled through in the
fire() method. In these four states this actor accepts and grants
requests for access to a shared resource. An Actor that wants to
request or be granted access to a shared resource must connect to
this controller via the requestInput and requestOutput ports. To
aid in monitoring such requests, the controller connects to a
ContentionAlarm actor through its contendInput and contendOutput
ports.

In state one the controller waits for requests on its requestInput
port. Once the first request has been received, the controller
moves to state two and sends a message to the ContentionAlarm
notifying it that a request has occurred at the current time. The
controller then moves to state three and performs a conditional
rendezvous on its contendInput and requestInput ports. Once an input
has been received from the ContentionAlarm, then the controller knows
that that the request contention period is over and it moves to state
four. In state four the controller notifies the resource requestors as
to whether their requests were granted based on priority relative to
other contenders.

@author John S. Davis II
@version $Id: Controller.java,v 1.38 2005/10/28 20:17:16 cxh Exp $
@since Ptolemy II 0.3
@Pt.ProposedRating Red (davisj)
@Pt.AcceptedRating Red (cxh)
*/
public class Controller extends CSPActor {
    /** Construct a Controller actor with the specified container
     *  and name.
     * @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 Controller(CompositeEntity cont, String name)
            throws IllegalActionException, NameDuplicationException {
        super(cont, name);

        requestOutput = new TypedIOPort(this, "requestOutput", false, true);
        requestInput = new TypedIOPort(this, "requestInput", true, false);
        contendOutput = new TypedIOPort(this, "contendOutput", false, true);
        contendInput = new TypedIOPort(this, "contendInput", true, false);

        requestOutput.setMultiport(true);
        requestInput.setMultiport(true);

        requestOutput.setTypeEquals(BaseType.BOOLEAN);
        requestInput.setTypeEquals(BaseType.INT);
        contendOutput.setTypeEquals(BaseType.GENERAL);
        contendInput.setTypeEquals(BaseType.GENERAL);
    }

    ///////////////////////////////////////////////////////////////////
    ////                     ports and parameters                  ////

    /** The resource request input port. Resource requests are made
     *  through this port with a token that include's the requestor's
     *  priority level. The type of this port is BaseType.INT. This
     *  port is a multiport.
     */
    public TypedIOPort requestInput;

    /** The resource request output port. Resources are granted through
     *  this port. The type of this port is BaseType.BOOLEAN. This port
     *  is a multiport.
     */
    public TypedIOPort requestOutput;

    /** The contention input port. The availability of data on this
     *  port indicates that additional resource contention does not
     *  exist at the current time. The type of this port is
     *  BaseType.GENERAL.
     */
    public TypedIOPort contendInput;

    /** The contention output port. Output data on this port can be
     *  used to trigger a ContentionAlarm. The type of this port is
     *  BaseType.GENERAL.
     */
    public TypedIOPort contendOutput;

    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////

    /** Execute this actor indefinitely.
     * @exception IllegalActionException If there is an error
     *  during communication through any of the input or output
     *  ports.
     */
    public void fire() throws IllegalActionException {
        super.fire();
        if (_numRequestInChannels == -1) {
            _numRequestInChannels = 0;

            Receiver[][] rcvrs = requestInput.getReceivers();

            for (int i = 0; i < rcvrs.length; i++) {
                for (int j = 0; j < rcvrs[i].length; j++) {
                    _numRequestInChannels++;
                }
            }
        }

        int br;
        int code;
        BooleanToken posAck = new BooleanToken(true);
        BooleanToken negAck = new BooleanToken(false);

        while (true) {
            //
            // State 1: Wait for 1st Request
            //
            _debug(new ExecEvent(this, ExecEvent.WAITING));

            ConditionalBranch[] requiredBranches = new ConditionalBranch[_numRequestInChannels];

            for (int i = 0; i < _numRequestInChannels; i++) {
                requiredBranches[i] = new ConditionalReceive(true,
                        requestInput, i, i);
            }

            br = chooseBranch(requiredBranches);

            if (br != -1) {
                IntToken token = (IntToken) requiredBranches[br].getToken();
                code = token.intValue();
                _winningPortChannelCode = new PortChannelCode(requestInput, br,
                        code);
            }

            //
            // State 2: Notify Contention Alarm of 1st Request
            //
            contendOutput.send(0, new Token());

            //
            // State 3: Wait for Contenders and Send Ack's
            //
            _debug(new ExecEvent(this, ExecEvent.ACCESSING));
            _losingPortChannelCodes = new LinkedList();

            boolean continueCDO = true;

            while (continueCDO) {
                requiredBranches = new ConditionalBranch[_numRequestInChannels + 1];

                for (int i = 0; i < _numRequestInChannels; i++) {
                    requiredBranches[i] = new ConditionalReceive(true,
                            requestInput, i, i);
                }

                int j = _numRequestInChannels;
                requiredBranches[j] = new ConditionalReceive(true,
                        contendInput, 0, j);

                br = chooseBranch(requiredBranches);

                // Contention Occurred...and might happen again
                if ((br >= 0) && (br < _numRequestInChannels)) {
                    IntToken token = (IntToken) requiredBranches[br].getToken();
                    code = token.intValue();

                    if (code > _winningPortChannelCode.getCode()) {
                        _losingPortChannelCodes.add(0, _winningPortChannelCode);
                        _winningPortChannelCode = new PortChannelCode(
                                requestInput, br, code);
                    } else {
                        _losingPortChannelCodes.add(0, new PortChannelCode(
                                requestInput, br, code));
                    }
                } else if (br == _numRequestInChannels) {
                    //
                    // State 4: Contention is Over
                    //
                    _debug(new ExecEvent(this, ExecEvent.BLOCKED));

                    requiredBranches[br].getToken();

                    // Send Positive Ack
                    int ch = _winningPortChannelCode.getChannel();
                    requestOutput.send(ch, posAck);

                    // Send Negative Ack
                    Iterator losingPorts = _losingPortChannelCodes.iterator();
                    PortChannelCode pcc = null;

                    while (losingPorts.hasNext()) {
                        pcc = (PortChannelCode) losingPorts.next();
                        ch = pcc.getChannel();
                        requestOutput.send(ch, negAck);
                    }

                    // Prepare to Wait for New Requests...enter state 1
                    continueCDO = false;
                    _winningPortChannelCode = null;
                    _losingPortChannelCodes = null;
                }
                // All branches failed.
                else {
                    continueCDO = false;
                    return;
                }
            }
        }
    }

    ///////////////////////////////////////////////////////////////////
    ////                         public variables                  ////
    private int _numRequestInChannels = -1;

    private PortChannelCode _winningPortChannelCode;

    private List _losingPortChannelCodes;
}
TOP

Related Classes of ptolemy.domains.csp.demo.BusContention.Controller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.