csp::Alternative Class Reference

List of all members.

Detailed Description

A class for performing ALTs.

This class is featured in the Alternative section in the guide.

For those familiar with occam: this is a class for performing ALTs over a set of guards.

For those not familiar with occam: an ALT is a way for a process to select between multiple externally-originating events.

The most common use for an Alternative is to wait for input on a number of channels, but to only actually communicate on one of the channels. For example, a process might want to wait for input on either its data channel, or on a "control signal" channel, giving priority to the control signal. This could be achieved as follows:

            //dataIn is of type AltChanin<int>
            //controlIn is of type AltChanin<bool>
            //The boost::assign namespace is in scope, and <boost/assign/list_of.hpp> has been included
            
            bool signal;
            int data;
            
            Alternative alt( list_of<Guard*>(controlIn.inputGuard())(dataIn.inputGuard()) );
            
            while (true)
            {
                switch (alt.priSelect())
                {
                    case 0: //control signal:
                        controlIn >> signal;
                        ... Process the signal ...
                        break;
                    case 1: //data
                        dataIn >> data;
                        ... Process the data ...
                        break;
                }
            }

A channel guard (returned by AltChanin::inputGuard) is ready either when data is ready to be read from a channel, or when the channel is poisoned. If the channel is poisoned, and the guard for that channel is not selected (because a higher priority guard was ready) nothing special happens. If the guard for a poisoned channel is selected, fairSelect()/priSelect()/sameSelect() will return the index of the channel, and when you then try to read from the channel, a PoisonException will be thrown.

If you want to perform an extended input from the channel you are ALTing on, use the guard returned by AltChanin::inputGuard() as normal, but then in the body of the case statement below the ALT, perform an extended input instead of a normal input.

It is the user's responsibility to perform the input after the appropriate guard is selected. If you do not perform an input (or begin an extended input) as your first action (specifically, as your first action before performing any other channel communications or barrier synchronizations) then undefined behaviour may result, depending on the channel type involved.

Alternative is not usually a one-use class. It can best be thought of as a container for an array of guards that can then perform a fair ALT or PRI ALT on these guards any number of times (even switching between fairSelect and priSelect as you wish).

C++CSP v1.x Compatibility

In C++CSP v1.x, inputGuard() (and extInputGuard) took a parameter specifying where to store the data, and then the Alternative performed the input for you if that guard was selected. This is no longer the case, as evidenced by the change in the signature of inputGuard() (which will help you notice the problem in old code). Instead, the JCSP approach has been adopted, and you perform the input explicitly after the select method returns. This is no slower, is much easier to perform extended inputs (with the new ScopedExtInput class), simpler to deal with poison and allows you to be more flexible in where you store the result of each input, in exchange for putting a responsibility onto the user to remember to perform the input.

In C++CSP v1.x, the behaviour of an Alternative when a channel was poisoned was not explicitly defined, and could appear inconsistent in practice. This has now been explicitly defined above.

See also:
Guard


Public Member Functions

template<typename ITERATOR>
 Alternative (ITERATOR begin, ITERATOR end)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. ITERATOR must be an iterator similar to std::vector<Guard*>::const_iterator or std::list<Guard*>::const_iterator.
 Alternative (const std::vector< Guard * > &_guards)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
 Alternative (const std::list< Guard * > &_guards)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
 Alternative (Guard **const guardArray, const unsigned int amount)
 Constructor, taking the guard array.
unsigned int fairSelect ()
 Performs a fair ALT on the guard array.
unsigned int priSelect ()
 Performs a PRI ALT on the guard array.
GuardreplaceGuard (unsigned int index, Guard *guard)
 Replaces a guard in the array.
unsigned int sameSelect ()
 Performs a "same" ALT on the guard array.
 ~Alternative ()
 Destructor.


Constructor & Destructor Documentation

csp::Alternative::Alternative ( Guard **const   guardArray,
const unsigned int  amount 
)

Constructor, taking the guard array.

Note that this function does not actually take an array of guards as it needs to take advantage of inheritance from guards. Therefore it takes an array of pointers to guards.

Alternative copies guardArray so it ends up with its own copy of the array of pointers (that is not guardArray) but the pointers point to the same guards as guardArray. Upon destruction, Alternative will delete each individual guard itself so you should not delete the guards yourself.

Parameters:
guardArray Pointer to the array of guard pointers
amount The length of guardArray

csp::Alternative::Alternative ( const std::list< Guard * > &  _guards  )  [inline]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

csp::Alternative::Alternative ( const std::vector< Guard * > &  _guards  )  [inline]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<typename ITERATOR>
csp::Alternative::Alternative ( ITERATOR  begin,
ITERATOR  end 
) [inline]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. ITERATOR must be an iterator similar to std::vector<Guard*>::const_iterator or std::list<Guard*>::const_iterator.

It will be passed to the constructor of std::vector<Guard*>. It is not advisable that you use std::set<Guard*>::iterator, because the order of the guards is important, and std::set will order the guards somewhat arbitrarily.

csp::Alternative::~Alternative (  ) 

Destructor.

It destroys all the guards in its guard array


Member Function Documentation

unsigned int csp::Alternative::priSelect (  ) 

Performs a PRI ALT on the guard array.

A PRI ALT returns when one of the guards is ready. If more than one is ready then the earliest in the guard array is always picked.

Returns:
The index of the guard that was picked

unsigned int csp::Alternative::fairSelect (  ) 

Performs a fair ALT on the guard array.

A fair ALT returns when one of the guards is active. Over a number of calls it evens out the precedence given to each of the guards so that they are all given equal chance (over many calls) of being selected over the other guards.

It is equivalent to performing a PRI ALT while cycling the order of the guards each call.

Returns:
The index of the guard that was picked

unsigned int csp::Alternative::sameSelect (  ) 

Performs a "same" ALT on the guard array.

A "same" ALT returns when one of the guards is active. Each time it gives precedence to the guard that was activated last time.

It is useful for multiplexors where continual data bursts are likely to come on a channel, to speed up inputting from the same channel many times in a row.

Returns:
The index of the guard that was picked

Guard * csp::Alternative::replaceGuard ( unsigned int  index,
Guard guard 
)

Replaces a guard in the array.

This method is useful for changing timeout guards in an ALT without constructing a new ALT.

Parameters:
index The index of the guard to replace
guard The new guard
Returns:
The old guard, must be deleted or otherwise dealt with


Generated on Mon Aug 20 12:24:28 2007 for C++CSP2 by  doxygen 1.4.7