ALT
s.
This class is featured in the Alternative section in the guide.
For those familiar with occam: this is a class for performing ALT
s 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).
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.
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. | |
Guard * | replaceGuard (unsigned int index, Guard *guard) |
Replaces a guard in the array. | |
unsigned int | sameSelect () |
Performs a "same" ALT on the guard array. | |
~Alternative () | |
Destructor. |
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.
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.
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
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.
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.
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.
Replaces a guard in the array.
This method is useful for changing timeout guards in an ALT without constructing a new ALT.
index | The index of the guard to replace | |
guard | The new guard |