Communicating Process Architectures 2000 P.H. Welch and A.W.P. Bakkers (Eds.) IOS Press, 2000
77
Conditional Communication in the Presence of Priority Gerald H. Hilderink and Jan F. Broenink University of Twente, P.O.Box 217, 7500 AE Enschede Control Laboratory, The Netherlands
[email protected]
Abstract. In this paper the behavior of conditional communication in the presence of priority will be described. In the theory of CSP, conditional communications are expressed by a (external) choice construct—also known as the alternative construct—by which the choice of one communication out of a set of communications is non-deterministic. In practice, some communication can be more important than others, so that, the choice is deterministic. Therefore, one can distinguish two prioritized alternative constructs; a symmetric alternative construct (ALT) and an asymmetric alternative construct (PRIALT). Current formal semantics and implementations of the ALT and PRIALT are based on the priorities of communication and not related to the surrounding priorities of communicating processes. This can result in a structural mismatch that can cause performance problems. In this paper a practical solution for realizing fair and unfair conditional communication in the presence of the PAR and the PRIPAR will be discussed.
1. Introduction Purely parallel languages can be given adequate semantics by models whose only primitives are communications, such as CSP’ failure/divergences model, since one part of a program can only influence a disjoint part by communication [13]. The theory of Communicating Sequential Processes (CSP) [6,7,14] specifies fundamental synchronization primitives, based on processes and communication between processes. Fundamental operators specify whether processes execute in sequence, in parallel, or by some choice. The interaction between concurrent processes is performed by communication via channels. Channel communication can be unconditional or conditional. Unconditional communication is when two processes communicate and conditional communication is an alternation, or a choice, between more than one communication. The essence of alternation is that it acts as an arbiter between a number of concurrently presented alternative communications. An alternation combines a number of processes guarded by communication—inputs or outputs on channels. If a number of parallel processes becomes committed to communication with guarded processes then the arbiter will select exactly one communication. The alternation performs the process associated with the guard being ready. In CSP, such a conditional communication pattern is known as the alternative construct. The choice that is made is non-deterministically. Thus, in theory, the choice of one communication out of a set of communications is arbitrary. In practice, the internal choice mechanism is more or less deterministic and the implementation will always select a particular branch. Under the formal semantics any way of
78
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
making an alternative choice is legal—including some random mechanism or a grossly fair one [13]. A fully deterministic mechanism is still a valid implementation of a non-deterministic specification. In software, some fairness can be desired by which each choice has equal probability or some unfairness can be desired by which some communication is more important than others. Therefore, we distinguish two prioritized alternative constructs; a symmetric (or fair) alternative construct (ALT) and an asymmetric (or unfair) alternative construct (PRIALT). These constructs are of major importance in many programs. Both constructs are legal alternatives in CSP and are defined in occam [8]. The occam language model is tightly related to CSP. We use occam for pseudo-coding the examples in this paper. A shortcoming of CSP is that it does not treat any notion of priority. Thus, the PRIALT and PRIPAR are not treated in CSP. CSP abstracts from those details and specifies the PAR and ALT being non-deterministic. In general, CSP does not specify the behavior of scheduling of processes (i.e., threads) as is done in occam. Lawrence [11] extended CSP with a general treatment of priority, called CSPP, but it is not clear whether there is a direct association between the priority of the client processes and the preferences given by the ALT or PRIALT. In occam, there is no such an association and therefore the programmer is expected to do the necessary mapping. An unfortunate mapping of PRIALTs and PRIPARs can cause a structural priority mismatch resulting in a performance penalty. In circumstances where the priority of a process is changing (due, for example, to the use of deadline-driven scheduling or priority inheritance) use of a static mapping would no longer be adequate [2]. In software, the notion of priorities is an important property of the ALT and PRIALT, but also an important property of the PAR and PRIPAR. These properties allow specifying the fairness and unfairness of scheduling of processes or choosing between events. These properties are coherently related to each other and managed by the underlying kernel. This paper illustrates the notion of priority by showing that the ALT and PRIALT should adapt their decision to the priorities of the surrounding client processes. This solution eliminates the above-mentioned mismatch problem. 2. Unconditional and conditional communication In CSP communication between processes can appear as unconditionally or conditionally. 2.1 Unconditional communication Unconditional communication is when two processes engage in communication. As described by Jones [9], the important thing about unconditional communication is that once an unconditional communication has become possible, it must happen eventually. An unconditional communication, as soon as it becomes possible, makes an offer to its peer. A process receiving an offer knows that the sender cannot withdraw the offer, because he is already committed to the communication. For example, example 1 illustrates two communicating processes. PAR chan!x chan?y
–- writer process –- reader process
Example 1: communicating processes in parallel.
The writer process (chan!x) and the reader process (chan?y) run in parallel and both processes will rendezvous on the channel chan. This means that if the writer process is ready to transmit then it will block until the reader process is ready to receive. Similarly, if the reader process is ready to receive it will block until a writer process is ready to transmit. A blocked process
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
79
consumes no processor time and another process will run instead. When both processes are ready for communication—one outputs on the channel and the other inputs on the channel— they are engaging in the same communication event. On communications, data will be copied from source variable x into destination variable y. After communication both processes continue. 2.2 Conditional communication With conditional communications several communications between processes are under the condition that only one of them will actually happen. A decision has to be made about which one of those possible conditional communications will happen, i.e. an alternation between more than two communications. Not until that decision has been taken any of them are committed to happen. The decision between alternative communications can be based on an arbitrary choice, so called alting. In CSP, such an arbitrary choice of one of those communications introduces nondeterminism to the process that is doing the alting, i.e., it is not under the control of that alting process or anyone else. If the environment of an alting process is offering several events (e.g. channel inputs, channel outputs, timeouts, skips), the alting process makes an arbitrary choice of one of those events. Once the choice of one of those events is made the process that is followed by this event will be executed. These events are an integral part of the decision even though it is tempting to think that this process is a choice between the guarded processes. The conditional peer appears as a guard—guarding the process—and the other unconditional peer is not a guard. A guard consists of an event and a process, with the assumption that the process can commit in this event as the first event it must engage in. A guard is said to be ready, when there is a process already committed to this event. A conditional peer can be an input-guard or output-guard (not allowed in occam), but also a timeout-guard or skip-guard which are not treated in this paper. As mentioned in section 1, a conditional communication pattern is known as the alternative construct. When its guards are treated as being equally important then the selection criteria is symmetric, but when its guards favors over other guards then the selection criteria is asymmetric. Therefore, we distinguish two alternative constructs: the symmetric alternative construct (ALT) and the asymmetric alternative construct (PRIALT). 2.2.1 Symmetric alternative construct (ALT) A symmetric alternative construct considers each guard to be equally important. Example 2 illustrates a symmetric alternative construct with two guards each guarding a process, respectively P and Q. WHILE TRUE ALT chan1?request -- read operation: on communication read request value from chan1 -- perform process P P(request) chan2!object -- write operation: on communication write object to chan2 -- perform process Q Q(object) Example 2: alternative construct.
Here, process P is guarded by chan1 and process Q is guarded by chan2. If chan1 is the only channel being ready, i.e. a client process is committed in communication on chan1, then the ALT will select the guard by successively executing the read operation chan1?request and
80
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
process P(request). If chan2 is the only channel being ready then the ALT will select the guard by successively executing the write operation chan2!object and process Q(object). The selection criterion used is that the guards have equal priorities. If both guards are ready then one of the guards will be randomly selected. If no guard is ready then the ALT will wait until at least one guard becomes ready, i.e. at least one client process is willing to communicate. The ALT terminates when the selected process terminates. 2.2.2 Asymmetric alternative construct (PRIALT) In practical situations, one event can be more important than other events. In other words, some events favors over other events. In these circumstances, the choice is asymmetric. The asymmetric alternative construct, called PRIALT, is priority-ordered and assigns declining priorities to the list of guards. WHILE TRUE PRIALT chan1?request -- read operation: on communication read request value from chan1 -- perform process P P(request) chan2!object -- write operation: on communication write object to chan2 -- perform process Q Q(object) Example 3: priority-ordered alternative construct.
The selection criterion used is that the guards have different (declining) priorities. The alteration will input values from chan1 in preference to outputs to chan2. Thus, the alternation will select guard chan1?request in favor for guard chan2!object when both are ready. 2.2.3 Unconditonal and conditonal guards A guard can be conditional or unconditional (do not confuse with conditional and unconditional communication) in that each conditional guard can be enabled or disabled according to its condition of resp. true or false. A disabled guard will be omitted by the selection mechanism. Unconditional guards, as in example 3, are always enabled. Example 4 illustrates two conditional guards. WHILE TRUE ALT (t>30) & chan1?request -- read operation: on communication read request value from chan1 -- perform process P P(request) (x30) is true then chan1 will be checked otherwise it will be omitted and the guarded process P will not be selected. This is similar for the second guard. When both conditions are true, this example is equal to example 2.
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
81
2.2.4 Alting disagreement Jones [9] describes that if each process tries to communicate by a conditional communication then they must both make the same decision about whether they want to communicate. Any attempt to make the decision independently at each process is likely to lead to a disagreement, especially for ‘truly’ concurrent or physically separated processors. For example, two communicating alting processes—performing conditional communication at each peer—will never commit in communication as illustrated in the following example: PAR ALT chan!x -- write operation: on communication write x value to chan -- perform process P P() ... ALT chan?y -- read operation: on communication read y from chan -- perform process Q Q(y) ... Example 5: alternative disagreement.
A solution is imposing restrictions on the way in which conditional communications can legally be used in programs. The restriction adopted in occam is to ensure that no pair of conditional communications ever meet. Whenever a pair of communications matches, at least one is guaranteed to be unconditional. Jones shows that the restriction is to eliminate output guards and that input guards are sufficient (programming without input guards is less natural than programming without output guards). This means that in each pair of communicating processes there is an output, which is necessarily unconditional. He illustrates that each output guard can be replaced by a communication pattern with an input guard. The following example 6 shows a replacement of the output guard of example 2 into an input guard. WHILE TRUE ALT chan1?request -- read operation: on communication read request value from chan1 -- perform process P P(request) chan3?request -- read operation: on communication read request from chan3 chan2!object -- write operation: on communication write object to chan2 -- perform process Q Q(object) Example 6: alternative construct with only input guards.
The caller of chan3 must be adapted as well; first it must output a request on chan3 (chan3!request) and then it must read the object from chan2 (chan2?object). This workaround is an effective solution, but calls for extra channel communications and expansion of the communication protocol between processes. This may restrict some design
82
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
freedom and lowers efficiency. In legal circumstances an output guard may simplify the design and is faster than applying the workaround with an input guard. Instead of imposing restrictions, another solution is to allow output guards when it suites best where by the above mentioned hazard should be detected by tools before run-time and resulting in warnings for the user. These semantic rules can be checked during design to make the designer aware of possible dangers and these rules can be checked afterwards for the finishing touch resulting in errors. This can be accompanied with checking other semantic rules. We elaborate more on this issue in section 3.3. 3. Alting with notion of priority In the theory of CSP, the ALT is an arbitrary choice construct and does not specify any fairness or unfairness. Thus, any way of making a choice, i.e. fair or unfair, is legal. It must not concern the programmer or user of the alting process how the choice is made. In software, assigning priorities to the execution of processes is an important solution when processes are scheduled on a single processor and when their deadlines must be met. The underlying mechanism is often deterministic and therefore we must distinguish between fairness and unfairness to specify the deterministic decisions in software. A fair decision is made with respect to previous decisions the mechanism has made. An unfair decision can be any decision that is not a fair decision, which is trivial of course. In this paper we present the symmetric alternative construct (ALT) as the purely fair alternative construct and the asymmetric alternative construct (PRIALT) as a particular unfair alternative construct. However, there are circumstances whereby the PRIALT is preferred to be fair and not being unfair. The nature of fairness or unfairness is a matter of proper dealing with the priorities of processes and with the priorities of communication events. 3.1 Logical alting versus preference alting The PRIALT, as described in section 2.2.2, uses a most trivial deterministic mechanism and is of major importance in many programs. The unfairness (or asymmetric) criteria used are that the guards have different (declining) priorities. Roscoe [13] describes a fair alting mechanism for occam based on a PRIALT with the use of conditional input guards, see example 7. SEQ PRIALT (i ≤ 0) & g0 i = 1 (i ≤ 1) & g1 i = 2 ... ... (i ≤ n-2) & gn-1 i = n-1 gn-1 i = 0 (i > 0) & g0 i = 1 (i > 1) & g1 i = 2 ... ...
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
83
(i > n-2) & gn-1 i = n-1 CASE i 1 P0 2 P1 ... ... n-1 Pn-2 0 Pn-1 Example 7: alternative construct with conditional input guards.
Here, gi is a guard and the CASE performs branches to the process Pi. This solution guarantees that no guard can be activated twice while there is another one waiting. The conditions provide a fair priority ordering among the guards. The fairness (or symmetric) criteria used are that the guards are round-robin prioritized with the guard chosen last time getting lowest priority next time. Still we can say that the guards under the ALT have equal priority. A slightly simpler solution or a fair ALT is given by Lau and Shea [10] using occam 2, which is basically the same as the one above. The behavior of fairness and unfairness can be described by specifying the notion of priority for each of them. The semantics of the fair ALT as described by Roscoe [13] and the PRIALT by Lawrence [11] are isolated to the alting process. These descriptions of round-robin implementation for the ALT and priority-ordering implementation for the PRIALT are basically cyclic (non-busy) polling mechanisms that test the readiness of each guard in a cyclic fashion. A description about the implementation and properties of the PRI ALT can be found in Barret et al. [1]. These implementations are for instance found in kernels of occam (including occam translators such as KroC [16] and SpoC [12]), the transputer, and the CSP for Java kernels JCSP [15] and CTJ [4]. These decision mechanisms are focused on the logical priorities of its guards and not on the priorities of its client processes. We call this alting process logical alting. Burns [2,3] noticed that the programmer is expected to do the necessary mapping. In circumstances where the priority of a process is changing (due, for example, to the use of deadline-driven scheduling or priority inheritance) use of a static mapping would no longer be adequate. For example, an unfortunate mapping of a PRIALT and its client processes in a PRIPAR can cause a structural priority mismatch resulting in a performance penalty. Even the ‘fair’ mechanism of the ALT can become unfair in contrast to the priorities of the client processes. Some applications may experience more trouble than others, but for real-time applications these problems can have a significant burden on the deadlines. We think that these implementations are inefficient (i.e. not optimal) for real-time software. A solution is to adapt the decision mechanism in such a way that it is focused on the preference priority of its guards and also focused on the priorities of the surrounding client processes. Important is that the priorities of the client processes should dominate over the priorities of the guards. We call this alting process preference alting. The examples in the following subsections will illustrate the problems of logical alting and its corrections that are performed by preference alting. These examples illustrate the behavior of alting in the presence of a PAR or PRIPAR on a single processor system, because priorities relations between processes have only meaning on a shared processor. On such a system, we assume that the underlying mechanism is deterministic which always will result in a single trace of communications. The trace of communication is a sequence of communication events in order of occurrence between angled brackets . As we speak of an ALT we mean a purely fair ALT.
84
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
PAR c2!a c1!b WHILE i pri(b) | a.thread.priority < b.thread.priority Ù a.thread ¹ b.thread Ù a ¹ b } The occurrence times ta and tb of the events a and b in a deterministic environment can never be the same, so, here ta ¹ tb. The operator W% is defined in the following manner: def
(x:A → P(x)) W% (y:B → Q(y)) = z:C → R(z)
94
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
where R(z)
=
P(z)
if z Î A - B
=
Q(z)
if z Î B - A
=
P(z)
if z Î A I B and pri(x) > pri(y)
=
Q(z)
if z Î A I B and pri(x) < pri(y)
=
P(z)
if z Î A I B and pri(x) = pri(y) and ta < tb
=
Q(z)
if z Î A I B and pri(x) = pri(y) and ta > tb
s The operator W% is defined in the following manner: def s (x:A → P(x)) W% (y:B → Q(y)) = z:C → R(z)
where R(z) =
P(z)
if z Î A - B
=
Q(z)
if z Î B - A
=
P(z)
if z Î A I B and pri(x) > pri(y)
=
Q(z)
if z Î A I B and pri(x) < pri(y)
=
P(z)
if z Î A I B and pri(x) = pri(y)
4.2 Properties of alting s s s In this section we will give some properties of alting for the operators W , W , W& , W& , W% and W% . On the basis of these properties we can observe any constructive parallels.
As mentioned in the previous section, the operator W is idempotent, commutative and associative. ( a → A )W( a → A ) = (a → A ) ( a → A )W(b → B ) = (b → B )W( a → A )
( a → A )W((b → B )W(c → C )) = (( a → A )W(b → B) )W(c → C )
s Operator W is idempotent and associative, but not commutative.
s ( a → A )W( a → A ) = ( a → A ) s s ( a → A )W( b → B) ≠ ( b → B )W( a → A ) s s s s ( a → A )W((b → B )W(c → C )) = (( a → A )W(b → B ))W(c → C )
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
95
Operator W& is idempotent, associative and partially commutative. ( a → A )W & ( a → A ) = (a → A )
( a → A )W & (b → B ) ≈ (b → B )W& ( a → A )
& ((b → B )W & (c → C )) = (( a → A )W & (b → B) )W& (c → C ) ( a → A )W
Operator W& is partially commutative. If both events a and b are ready then ( a → A )W& (b → B ) will initially select process ( a → A ) and ( b → B )W& ( a → A ) will initially select ( b → B ) , assuming that the left process is the first in the list of guards and the right process is the second in the list of guards under the alternative construct. This is because by the fact that i is always initially 0. At multiple runs the alternations of both left-side and right-side processes seem to be statistically equal. s Operator W& is idempotent and associative, but not commutative. s ( a → A )W& ( a → A ) = ( a → A ) s s& ( a → A )W& ( b → B) ≠ ( b → B )W (a → A) s s& s& s ( a → A )W& (b → B )W (c → C ) = ( a → A )W (b → B ) W& (c → C )
(
) (
)
s Operator W& is not commutative. If both events a and b are ready then the left-side process will be selected, assuming that the left process is the first in the list of guards and the right process is the second in the list of guards under the alternative construct. Operator W% is idempotent, commutative and associative, equally to the W operator. ( a → A )W % ( a → A ) = (a → A )
( a → A )W % (b → B ) = (b → B )W% ( a → A )
% ((b → B )W % (c → C )) = (( a → A )W % (b → B) )W% (c → C ) ( a → A )W
s Operator W% is idempotent, associative and partially commutative.
s ( a → A )W% ( a → A ) = ( a → A ) s s% ( a → A )W% (b → B) = ( b → B )W ( a → A )| pri( a ) ≠ pri (b )
{ } {( a → A )Ws% (b → B) ≠ (b → B )Ws%( a → A )| pri (a ) = pri (b )} s s% s s% ( a → A )W% ((b → B )W (c → C )) = (( a → A )W% (b → B ))W (c → C )
If pri(a) = pri(b) then the preference choice operator shows similarities with the logical choice operators:
96
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
% ( a → A )W & (b → B ) pri (b )} ⇔ s s& ( a → A )W% (b → B )| pri (a ) = pri (b ) ⇔ ( a → A )W (b → B )
{( a → A )W% (b → B )| pri (a ) =
{
}
Here, the preference symmetric choice operator is only statistically equal to the logical symmetric choice operator. They differ in the initial run. If pri(a) ¹ pri(b) then the preference symmetric choice operator shows similarities with the preference asymmetric choice operator:
{( a → A )W% (b → B )| pri (a ) ≠
pri (b )} ⇔ s% ( a → A )W(b → B )| pri (a ) ≠ pri (b ) ⇔ s (b → B )W% ( a → A )| pri (a ) ≠ pri (b )
{ {
} }
Any difference in priority, e.g. pri(a) < pri(b), turns the preference asymmetric choice operator into a specific logical asymmetric choice operator:
{( a → A )Ws% (b → B )| pri (a ) < pri (b )} ⇔ {(b → B )Ws%( a → A )| pri (a ) < pri (b )} ⇔ (b → B )Ws& (a → A) The semantics of these choice operators are legal in CSP. Preference alting is an extension of the semantics of logical alting. This extension removes obstacles when temporal requirements must be met. Also, the semantics of preference alting provides the ability of dynamic scheduling. For this we only need to introduce a dynamic PRIPAR. 5. Conclusions In real-time software the use of priorities is a common solution to allow processes to share the processor while meeting the temporal requirements. The notion of priority is not treated in CSP. Hence, the PRIALT and PRIPAR are not treated in CSP. The desire of extending CSP with notion of priority is known since the development of the PRIPAR and PRIALT in occam. CSP abstracts from those details and specifies the PAR and ALT being non-deterministic. In general, CSP does not specify the behavior of scheduling of processes (i.e., threads) as in occam. Although the occam model embraces some notion of priority, there is no direct association between the priority of the client processes and the preferences given by the ALT or PRIALT. The programmer is expected to do the necessary mapping. An unfortunate mapping of ALTs, PRIALTs and PRIPARs in a composition can cause a structural priority mismatch resulting in a performance penalty. In circumstances where the priority of a process is changing (due, for example, to the use of deadline-driven scheduling or priority inheritance) use of a static mapping would no longer be adequate. The introduction of preference ALTing can contribute to better understanding of the notion of priorities. Preference alting is an extension of the semantics of logical alting. This extension removes obstacles when temporal requirements must be met. Also, the semantics of preference alting provides the ability of dynamic scheduling. For this we only need to introduce a dynamic
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority
97
PRIPAR. Important is that any inadequate mapping that is caused by conflicting priorities of process will always be corrected by the preference ALTs. Remarkably, a (logical) PRIALT is known as an unfair ALT, but the preference PRIALT adapts it behavior to the priorities of the surrounding client processes and becomes fair! Also remarkably is that the necessity for output guards become motivated when dealing efficiently with priority. Output guards can reduce the burden of priority inversion and increase the performance of alting. Caution should be taken when input guards and output guards are used. The preference ALT and preference PRIALT have been implemented in CTJ with success. References [1]
Barrett, G., Goldsmith, M., et al. (1988), The meaning and implementation of PRI ALT in occam, 9th occam User Group, Occam and the Transputer--Research and Applications, Southampton,pp. 37-46, IOS Press.
[2]
Burns, A. (1987), Occam's priority model and deadline scheduling, 7th Occam User Group & International Workshop on Parallel Programming of Transputer based Machines, Grenoble, LGI-IMAG.
[3]
Burns, A. and Wellings, A. (1990), Real-Time Systems and their Programming Languages, Addison-Wesley Publishing Company.
[4]
Hilderink, G.H., Communicating Threads for Java (CTJ) home page, http://www.rt.el.utwente.nl/javapp.
[5]
Hilderink, G.H., Bakkers, A.W.P., et al. (2000), A Distributed Real-Time Java System Based on CSP, The Third IEEE International Symposium on Object-Oriented Real-Time Distributed Computing (ISORC-2000), Newport Beach, California,pp. 400-407, IEEE Computer Society.
[6]
Hoare, C.A.R. (1978). “Communicating Sequential Processes.” CACM 21(8): pp. 666-677.
[7]
Hoare, C.A.R. (1985), Communicating Sequential Processes, London, United Kingdom, Prentice Hall.
[8]
INMOS (1988), occam 2 Refernce Manual, Prentice Hall.
[9]
Jones, G. (1987), On Guards, 7th Occam User Group & International Workshop on Parallel Programming of Transputer based Machines, Grenoble, LGI-IMAG.
[10] Lau, F.C.M. and Shea, K.M. (1988), Mapping a Process Network onto a Processor Network, 9th occam User Group, Occam and the Transputer--Research and Applications, Southampton,pp. 91-112, IOS Press. [11] Lawrence, A.E. (1998), Extending CSP, 21th World Occam and Transputer User Group Technical Meeting, Architectures, Languages and Patterns for Parallel and Distributed Applications, Canterbury, United Kingdom,111-131,5-8 April 1998, IOS Press. [12] Nicole, D.A., The Southampton Portable occam Compiler (SpoC), http://gales.ecs.soton.ac.uk/software/spoc/ . [13] Roscoe, A.W. (1987), Routing messages through networks: an excercise in deadlock avoidance, 7th Occam User Group & International Workshop on Parallel Programming of Transputer based Machines, Grenoble, LGI-IMAG. [14] Roscoe, A.W. (1998), The Theory and Practice of Concurrency, Prentice Hall. [15] Welch, P.H. and Austin, P.D., The JCSP home page, http://www.cs.ukc.ac.uk/projects/ofa/jcsp. [16] Welch, P.H., Moores, J., et al., The KroC home page, http://www.cs.ukc.ac.uk/porjects/ofa/kroc.
98
G.H.Hilderink and J.F.Broenink / Conditional Communication in the presence of priority