Kent Academic Repository: Full Text Document PDF
Kent Academic Repository: Full Text Document PDF
DOI
Document Version
UNSPECIFIED
Versions of research
The version in the Kent Academic Repository may differ from the final published version.
Users are advised to check http://kar.kent.ac.uk for the status of the paper. Users should always cite the
published version of record.
Enquiries
For any further enquiries regarding the licence status of this document, please contact:
[email protected]
If you believe this document infringes copyright then please contact the KAR admin team with the take-down
information provided at http://kar.kent.ac.uk/contact.html
TRANSPUTER COMMUNICATIONS, VOL. 3(3), 1–18 (AUGUST 1997)
SUMMARY
When building concurrent systems, it would be useful to have a collection of reusable processes
to perform standard tasks. However, without knowing certain details of the inner workings of
these components, one can never be sure that they will not cause deadlock when connected to
some particular network.
Here we describe a hierarchical method for designing complex networks of communicating
processes which are deadlock-free. We use this to define a safe and simple method for specifying
the communication interface to third party software components. This work is presented using
the CSP model of concurrency and the occam2.1 programming language.
KEY WORDS deadlock livelock design concurrency reuse components networks CSP occam
1 INTRODUCTION
Code reusability is an important consideration in large-scale system design. It is an issue
which modern programming languages are expected to address. In the concurrent pro-
gramming language, occam2.1 [1], arbitrarily complex subnetworks of processes may be
concealed within a single process definition. The internal structure of such a process may
be changed independently from any network in which it is embedded. This is extremely
useful for a number of reasons. However, in the context of concurrent systems, it is also
potentially dangerous. Unless we know their internal details, how can we be sure that a
program which incorporates these components is not prone to deadlock?
Deadlock is a major problem with parallel programming. Safety critical systems must
be guaranteed deadlock-free, but this is not an easy task. In [2] and [3] it is shown how
to tackle this problem using software design rules. By placing minor restrictions on the
manner in which concurrent systems are constructed, it is possible to remove completely
the spectre of deadlock. Proofs of deadlock-freedom for networks of arbitrary size are
reduced to simple checks for local conditions of processes, and topological properties of
the network configuration.
In this paper we shall build on that work to show how deadlock-free networks may be
built hierarchically, incorporating reusable components. This provides an efficient method
for modular programming in occam2.1 that offers security guarantees that are very difficult
to obtain from traditional approaches to concurrent system design.
CCC 1070–454X/97/030001–18 Received 7 March 1996
c 1997 by John Wiley & Sons, Ltd. Revised 15 January 1997
2 J.M.R. MARTIN and P.H. WELCH
In section 2 we describe the deadlock analysis terminology of Roscoe and Dathi, which
is built upon the firm mathematical foundations of CSP. In section 3 we present a formal
definition of the client-server protocol which has previously existed only as a collection
of informal rules, potentially open to misinterpretation. We then prove a theorem about
how this protocol may be used to build deadlock-free networks and illustrate this by two
examples: an occam2.1 process farm and a message router. In section 4 we show how to use
the client-server protocol to build deadlock-free networks hierarchically from composite
sub-components. This is important for the design of large systems.
There are certain other design techniques which are known to yield deadlock-free con-
current systems. In section 5 we describe a technique for integrating subnetworks built
by different methods into a client-server system. Section 6 looks at the related issues of
divergence-freedom and starvation-freedom and section 7 describes ongoing research.
Q = a ! (b ! Q u c ! Q), Q = fa, b, cg
After it has performed event a, Q can refuse fg, fag, fbg, fcg, fa, bg, or fa, cg. Its maximal
refusals at this stage are fa, bg and fa, cg, which correspond to the two states that the process
may be in once it has decided which branch of the u construct to take: either it decides to
behave like b ! Q or it decides to behave like c ! Q. These are called stable states of Q
because once they are entered no internal activity is possible, at least until an external event
has been performed. Before making the decision as to which branch of the u construct to
take, Q is said to be in an unstable state. For the purpose of deadlock analysis, unstable
Processes
P
!
the alphabet of events for process P
!
e P first event e, then process P
!
c?x P first input x from channel c, then process P
c!y P first output y to channel c, then process P
2
u
P Q external choice of P or Q
k
P Q internal choice of P or Q (non-deterministic)
P Q P in parallel with Q
nf g f g
P ; Q P followed by Q
P e1 , , en :: P with all occurrences of events e1 , : : , en hidden
P <
boolean-expression >Q if boolean-expression then P else Q
Special Events
p successful termination
c.i communication of message i on channel c or
event ci
c.i.j communication of message (i, j) on channel c or
communication of message j on channel ci or
event cij
Traces
hi
h i
the empty trace
a, b, c the trace of events: a then b then c
(P)
#
traces the set of all finite traces of P
s c number of communications on channel c in trace s
]
j` f : : g
s the length of trace s
f : : , en g
s e1 , , en the trace s with all events removed save those in
e1 ,
P s = the process describing the behaviour of P after
it has performed trace s
states are irrelevant, as a system in such a state is yet to come to rest – when a system is
deadlocked there can be no activity at all.
Consider a network V of CSP processes, hP1 , : : , PN i, composed in parallel. Events which
lie in the alphabet of two processes of V require their simultaneous participation, and this is
the means of communication within the network. It is assumed that the network is triple-
disjoint – i.e. there is no event which is shared by more than two process alphabets. It is also
assumed that the network is busy – i.e. each process Pi is non-terminating and individually
free of both deadlock and divergence. (It is reasonably straightforward to extend the model
to allow for process termination, if required. See [6] for details.)
The behaviour of a network is described in terms of a set of states that it may be in. A
state of V consists of a trace of events s together with a tuple of refusal sets hX1 , : : , XN i such
that, for all i, (s j` Pi , Xi ) is a maximal failure of Pi . It represents a set of events in which
each process may refuse to engage after they have collectively performed the sequence of
events in s.
In a deadlock state every event is refused by some process, i.e.
[
N
Pi =
[ N
Xi
=
i 1 i 1 =
A network which has no deadlock states is said to be deadlock-free.
In any state = (s, hX1 , : : , XN i), if there is a process Pi which is ready to perform an event
(or events) which lie in the vocabulary of another process Pj (i.e. (Pi ; Xi ) \ Pj 6= fg),
we say that Pi is making a request of Pj , and write
Pi ! P
j
When a process has all its requests ungranted we say that it is blocked. In a deadlock state
every process is blocked.
3 CLIENT-SERVER NETWORKS
3.1 Client-Server Protocol
A particularly flexible design rule for deadlock freedom is the Client-Server Protocol. This
was originally formulated by P. Brinch Hansen [7] in the context of operating systems. It
has since been adapted as a means of designing deadlock-free concurrent systems using
occam2 (see [3]).
The basic idea is that a process communicates on each of its channels either as a client
or as a server, according to a strict protocol. A network of client-server processes is
deadlock-free if it has no cycle of client-server relationships.
The standard definition of the client-server protocol is both informal and intuitive. It
runs as follows. If a client is waiting to communicate with a server, the server, ignoring
possible indefinite delays whilst waiting to communicate as a client with another process,
must eventually become ready to participate in that communication.
Unfortunately this is too vague a condition to translate into a local specification of CSP
processes. For instance consider a process that acts only as a server. In order to establish the
above property we would need to show that any particular client request would eventually
be granted. To do this we would need to analyse the way in which the process interacts
with each of its other clients and possibly also how they interact with each of their clients
in turn. Here we introduce a formal definition which is slightly more restrictive than the
informal one, yet with the distinct advantage of being purely a property of an individual
process, independent of any network in which it is embedded. This is more suitable for
collaborative software projects and makes automatic checking much more feasible.
A basic client-server CSP process P has a finite set of external channels partitioned into
bundles, each of which has a type, in relation to P, which is either client or server. We write
the set of client bundles of P as clients(P), and the server bundles as servers(P).
Each channel bundle consists of either a pair of channels, a request and an acknowl-
edgement, hr, ai, or a single channel (which we call a drip) hdi. This allows client-server
conversations to be either one way or two way. In principle there is no reason why a bundle
should not contain three or more channels. In practice we have found that two channels are
generally sufficient, and have restricted the definition as such.
In the subsequent analysis, a communication event on a channel is represented purely
by the channel name, ignoring any data that is passed. The purpose of this is clarity
and simplicity. Following this convention, a basic client-server process, P, must obey the
following rules:
8(s, X) : failures(P). X= 6 P
(b) When P is in a stable state, either it is ready to communicate on all its request and
drip server channels or it is ready to communicate on none of them. In CSP terms,
this means that the refusal sets in the maximal failures of P include either none of its
request and drip server channels or all of them, i.e.
(d) When P communicates on a client request channel, it must guarantee to accept the
corresponding acknowledgement, i.e.
The formal statement of these rules is rather daunting, but it should be possible to design
conformant processes using only the informal descriptions which accompany them. Work
is in progress to develop software engineering tools (see Section 7) that will check for
adherence to the formal model, for total assurance.
When we construct a client-server network V from a set of client-server processes
hP1 , : : ,PN i, each client bundle of a process must either be a server bundle of exactly one
other process, or consist of channels external to the network. Similarly each server bundle
of any process must either be a client bundle of exactly one other process or be external to
the network. No other communication between processes is permitted.
The client-server digraph of a client-server network consists of a vertex representing
every process, and, an arc representing each shared bundle, directed from the process for
which it is of type client, towards that for which it is of type server.
Proof. First we observe that the matching requirements for client and server bundles
within a network enforce triple-disjointedness within a client-server network. This, coupled
with rule (a), ensures that client-server networks conform to the model of Roscoe and Dathi.
Then we use induction on the number of processes in the network. Suppose that the
theorem holds for any network with N processes. Consider a client-server network V =
hP1 , : : , PN +1 i, which has a circuit-free client-server digraph, yet has a deadlock state .
Without loss of generality we assume that PN+1 is maximal in the client-server ordering
of V . Every process is blocked in state , and therefore is making an ungranted request
to another process. Because of its maximality PN+1 can only make ungranted requests on
server channels. By rules (c) and (d) these cannot be acknowledge channels – they can only
be request or drip channels. By rule (b) it follows that P N+1 is making an ungranted request
on every one of its request and drip channels. So there is no process in the subnetwork
V 0 = hP1 , : : , PN i that is ready to communicate with PN +1 in state . Each process in V0 is
in fact blocked only by other processes in V 0, which implies that the subnetwork is itself
deadlocked. This contradicts our hypothesis that the theorem holds for networks of size N.
It follows that V must be deadlock-free. Clearly the theorem holds in the case when N = 1,
so by induction it holds for all N. Q.E.D.
3.2 Examples
A Simple Process Farm
We consider an application where computing-intensive tasks are performed in parallel
using a standard farm network configuration. A farmer employs n foremen each of whom
is responsible for m workers. The program is coded in occam2.12 as shown in Figure 2.
When each WORKER (i, j) becomes idle, it reports the result of any work done to its
FOREMAN (i) using channel a[i][j]. FOREMAN (i) reports this on channel c[i] to the
FARMER who, in turn, replies with a new task using channel d[i]. FOREMAN (i) then assigns
i i+1 )
1 A circuit in a digraph is a sequence of distinct vertices hv , v , : : , v i such that each pair of vertices (v , v
0 1 n
is connected by an arc, and also (v n , v0 ). A digraph containing no circuits is said to be circuit-free.
2 To make the examples more readable we take advantage of the support for user-defined data types in the
recently released occam2.1 language. These types, of course, have no impact on deadlock properties.
WORKER(0,0)
<a.0.0, b.0.0>
FOREMAN(0)
<a.0.(m-1), b.0.(m-1)>
FARMER
<a.(n-1).0, b.(n-1).0>
FOREMAN(n-1) <a.(n-1).(m-1), b.(n-1).(m-1)>
WORKER(n-1,m-1)
the new task to WORKER (i, j) with channel b[i][j]. Here the relationships between each
WORKER and its FOREMAN and between each FOREMAN and the FARMER are all client-to-
server (see Figure 3).
The CSP communication patterns for the component processes may be extracted as
follows:
It is straightforward to see that each process obeys the basic client-server protocol.
Clearly no individual process would ever terminate, deadlock or diverge if run in isolation
(rule (a)). Whenever a FARMER or FOREMAN process attempts to communicate on a
server request channel it offers the complete choice of such channels to its environment
(rule (b)). The WORKER processes are pure clients so rule (b) does not apply to them. Each
process communicates on each of its client request-acknowledgement pairs in alternating
sequence (rule (c)). And whenever a WORKER or FOREMAN process communicates on a
client request channel it immediately becomes ready to communicate on the corresponding
acknowledgement channel, and remains so until this communication takes place (rule (d)).
The FARMER is a pure server process for which rule (d) does not apply.
The client-server digraph of this network is illustrated in figure 3. It has no circuits and,
hence, the network is guaranteed deadlock-free.
It is usually safe to represent communication events in occam2 purely by their channel
names in the CSP specification, as was done here. The one exception is when using a
variant protocol on a particular channel. If the inputting process is unwilling to accept the
type of datum offered by the outputting process, a local deadlock may ensue. However, if
an exhaustive case list is offered by the inputting process there is no problem – but this
may be impractical. This issue is discussed in more detail in [8].
Note that the client-server ordering does not imply a single direction of dataflow. A
client-server bundle may contain both an input channel and an output channel.
A Message Router
NODE(0) NODE(1)
<0>
OUT IN
(0) (0)
IN <1> OUT
(1) (1)
IN OUT IN OUT
(4) (5) (6) (7)
OUT IN OUT IN
(4) (5) (6) (7)
<2>
OUT IN
(2) (2)
IN <3> OUT
(3) (3)
NODE(2) NODE(3)
Figure 4. Client-Server Digraph for the Message Router
Figure 4 shows the client-server digraph of a message routing program for a network
of processors. The processor topology illustrated is a square. Each processor is connected
to its horizontal and vertical neighbours by a link in each direction. Each processor runs
a separate process to control each of its input and output links. It also runs two interface
processes. One of these collects messages which have arrived at their destination, and
passes them to the local application program. The other routes messages from the local
application destined for other processors. The following routing strategy is employed. In
order to send a message to a processor with grid coordinates (x, y), first move it to a node
with the right x coordinate and then, keeping the x coordinate fixed, move it to the right y
coordinate. This strategy is easily generalised to an n dimensional grid – see [9].
In this case, each client-server bundle consists of a single drip channel, which makes it
particularly easy to verify adherence to the protocol – rules (c) and (d) not being relevant. In
fact each arrow in the client-server digraph corresponds to dataflow (by chance). Although
the processor configuration contains circuits, the client-server digraph of the processes
contains none, so the router is deadlock-free.
Note: The fact that the routing program is itself deadlock-free does not guarantee that
any program that incorporates it will not deadlock. Great care still needs to be taken [10].
4 COMPOSITE PROCESSES
A composite client-server process V is a client-server network hP1 , : : , PN i composed solely
from basic client-server processes and whose client-server digraph contains no circuits.
We define:
0N 1
[ [
@ clients(Pi) ; servers(Pj )A
N
clients(V ) =
0i=N1 j=1
1
[ [
@ servers(Pi ) ; clients(Pj )A
N
servers (V ) =
=
i 1 =
j 1
In other words the client and server bundles of V are those of the component processes Pi
which are not paired off.
We represent a composite client-server process by a single vertex in a client-server di-
graph. The following result shows that this is consistent with the composition rule governing
basic processes.
Proof. Consider the total client-server digraph formed when each composite process is
expanded back into its basic components. Since there are no cycles in the sub-digraphs
contributed by the composite processes and there is no cycle in the top-level digraph, there
can be no cycles in the total digraph. Theorem 1 allows us to conclude that the composite
network is deadlock-free. Q.E.D.
It is important to note that any basic client-server process is itself composite client-server
(although the reverse is not true). Hence we can apply the result to mixtures of composite
and basic processes. This theorem is clearly useful for designing networks hierarchically.
Complex subnetworks may be reused with ease. Black-box processes, that have been shown
to abide by the composite client-server specifications, may be safely incorporated.
However this theorem is too weak in some circumstances. We need to find a generalisa-
tion.
2 2
We define a dependency relationship between the server bundles and client bundles
of a composite process V. If x servers (V ) and y clients(V ) then x y means that
there is a path from the process with server bundle x to that with client bundle y, in the
client-server digraph of V.
a c
For example, figure 5 shows a composite client-server process TRIANGLE, with external
client-server channel bundles a, b, and c. Here we have:
(a b) and : (a c)
We construct an exploded client-server digraph of a network containing composite pro-
cesses in the following way. A node representing any composite process V is removed.
In its stead is placed a set of nodes – one for each server or client bundle of V . Each of
these is joined to its corresponding arc (that was formerly incident to the node representing
V ). Then we draw an arc from the node representing (server) bundle i to that representing
(client) bundle j if, and only if, i j in V .
Proof. As in Theorem 2, consider the total client-server digraph formed when each
composite process is expanded back into its basic components. As before, there are no
cycles in the sub-digraphs contributed by the composite processes. Therefore, if there were
a cycle in the total digraph, the construction rules for the exploded digraph mean that the
latter would also contain a cycle. Since the exploded digraph has no cycles, neither does the
total digraph and, by Theorem 1, the whole client-server network is deadlock-free. Q.E.D.
b b
a c a c
several client or server bundles, without losing any information. This depends on the
structure of the relation .
Therefore for deadlock-free design with composite client-server processes, we only need
to be told their client bundles, server bundles, and the dependency relation between them.
The benefit of Theorems 2 and 3 is that we avoid repeating superfluous information in the
diagrams we draw to design our programs. Instances of complex subnetworks are reduced
either to single nodes or to simplified representations when theorem 2 is too weak.
and where each process Pi 0 performs events in the alphabet of Pi as well as (possibly)
additional events that are external to the network, i.e.
6
i=j = ) (P ; P ) \ P
i
0
i j
0
= fg
The basic rule of thumb is that we may freely add client connections to any component
process Pi , but we may add server connections to at most one such process. The following
rules must be obeyed:
1. The additional channels of each process Pi 0 are partitioned into client and server
bundles, and Pi 0 must obey the basic client-server protocol on these bundles.
2. It is not permitted for more than one process Pi 0 to have server connections.
3. It is necessary to ensure that the new connections added to each process Pi do
not interfere with its internal behaviour. If communication on those channels were
concealed, P0i should behave identically to Pi , i.e.
Pi
0
n (P ; P ) i
0
i = Pi
The client-server bundles of V 0 are taken to be the disjoint union of those of each
component. It is clear that V 0 will adhere to rules (c) and (d) of the basic client-server
protocol (see section 3), since Rule 1 stipluates that each process Pi 0 does. Rule 2 ensures
that V 0 obeys rule (b) of the basic protocol. Rule 3 guarantees that V 0 is deadlock-free,
divergence-free and non-terminating – rule (a) of the basic client-server protocol. Hence,
V 0 may now be treated as a basic client-server process for the construction of client-server
networks that are automatically deadlock-free (provided the construction obeys the premise
of one of the theorems in this paper).
Rule 3 needs a little further explanation in the context of actual programming. In occam2
it means that if each communication on a client or server channel by Pi 0 were replaced by
SKIP, then Pi 0 would follow an identical communication pattern to P i .
KEYBOARD
USER.INTERFACE
I/O-PAR
subnet ROPE ROPE ROPE ROPE ROPE
GRAPHICS
In order that we may visualise this simulation, a graphics handling process, GRAPHICS,
is added to the I/O-PAR network using client-server connections. This process acts as a
server to each ROPE process along a single input channel. In this way, the position of each
rope section is periodically communicated to the graphics handler.
We also add a process USER.INTERFACE which communicates with each of the rope
elements as a client. To each rope process is added a corresponding polled server con-
nection. This mechanism is used to allow interactive keyboard control of the simulation.
USER.INTERFACE also has a server connection to a keyboard interface process KEYBOARD.
The client and server channels which were added to each component in the I/O-PAR
subnetwork of rope elements do not effect its internal communication pattern. Although
it has multiple disjoint server connections, they are only initiated by polling and so are
PAR
KEYBOARD (keyboard)
USER.INTERFACE (keyboard, new.parameters, acknowledge)
PAR i = 0 FOR n
ROPE (i, to.left[i], to.right[i],
to.right[i+1], to.left[i+1],
new.parameters[i], acknowledge[i],
display[i])
GRAPHICS (display)
non-blocking. It follows that the subnetwork formed from the ROPE processes behaves as
a single client-server process in relation to its environment. The client-server digraph for
the complete system is given in figure 7 – note that the I/O-PAR subnetwork should be
regarded as a single vertex. This digraph is free of circuits so the system is deadlock free.
Skeleton code for the resulting network is given in figures 8 and 9. The high-valency
and irregular communication topology of this program is not a problem for a network of
transputers. For first generation (T2/T4/T8) architectures, the Southampton Virtual Channel
Router[10] is part of the standard Toolset. For T9000s, the same idea is implemented
by hardware in the Virtual Channel Processor. These mechanisms remove the need for
communication design to be constrained to 4-valent topologies. This remains true for
occam retargetings to non-transputer multi-processors.
6 RELATED ISSUES
Apart from deadlock, there are two other major forms of pathological behaviour that
networks of communicating processes may exhibit: livelock and starvation.
Livelock is said to occur if the network becomes locked in an everlasting sequence
of internal communications, without ever communicating with its environment. It is a
particular form of divergence that occurs when internal communications are concealed.
This is a problem which may be every bit as catastrophic as deadlock. Fortunately it is a
relatively easy one to solve in client-server networks. If every component of a client-server
network has server connections and will always communicate on a server channel within a
finite number of actions, the network as a whole will be livelock-free – this is easily proved
by induction.
Starvation occurs to a particular process within a parallel network when it is held in a
perpetual state of waiting to communicate with another process or set of processes. In a
client-server network this might occur when two clients are competing for use of the same
server, but one of them is always favoured. In a message routing system, this would mean
that a message might never be delivered in heavy traffic. There is no way to deal with this
possibility of unfairness in the standard CSP model. However it can be tackled in occam2
with careful use of the PRI ALT construct [11].
The main advantage of this will be as follows. Grappling with CSP specifications will
not appeal to all programmers. Many will prefer to work from the informal statement of the
client-server rules using a high-level language directly. The model checker could be used
to provide total assurance that their code conforms to the formal requirements.
A different tool, based on the ideas in [2,3], is described in [15]. This allows designers
to work just with graphical representations of the system data-flow and to overlay this with
client-server digraphs. Currently, the tool checks designs against Theorems 1 and 2 (and
a similar result concerning I/O-PAR networks) to ensure that only deadlock-free systems
can be created. For each basic process, the tool generates template occam (serial) code
with a communication structure that satisfies Rules a, b, c and d from Section 3. Code
for state declaration, initialisation and maintenance has to be added but, so long as no
infinite computational loops are introduced, this has no impact on these rules. For higher-
level components (e.g. those implemented by client-server sub-networks), the full occam
parallel code is produced.
Work is in progress to extend this tool to accept the dependency relationship (Section
3), to check designs against the more flexible Theorem 3 and to support the use of hybrid
paradigms (as defined in Section 5). The attraction of tools such as this is that deadlock-free
designs can be constructed graphically (top-down, bottom-up or both) without the designer
needing fluency in either CSP or occam, and with all the parallel and communication
servicing code generated automatically. The tool knows the theorems and the designer
learns from the tool.
REFERENCES
[1] SGS-Thomson Microelectronics. occam2.1 Reference Manual, 1995. Also available from
< URL:http://www.hensa.ac.uk/parallel/occam/documents/ . >
[2] J. Martin, I. East, and S. Jassim. Design rules for deadlock freedom. Transputer Communica-
tions, 2(3):121–133, September 1994. ISSN 1070-454X.
[3] P.H. Welch, G.R.R. Justo, and C. Willcock. High-level paradigms for deadlock-free high-
performance systems. In Grebe et al., editors, Transputer Applications and Systems ’93, pages
981–1004, Amsterdam, 1993. IOS Press. ISBN 90-5199-140-1.
[4] A.W. Roscoe and N. Dathi. The pursuit of deadlock freedom. Technical Report Technical
Monograph PRG-57, Oxford University Computing Laboratory, 1986.
[5] C.A.R. Hoare. Communicating Sequential Processes. Prentice Hall, 1985.
[6] N. Dathi. Deadlock and Deadlock-Freedom. D.Phil thesis, Oxford University Computing
Laboratory, 1991.
[7] P. Brinch Hansen. Operating System Principles. Prentice Hall, 1973.
[8] B. Scattergood and K. Seidel. Translating occam2 into csp. In Transputer Applications and
Systems ’94, pages 416–430, Amsterdam, September 1994. IOS Press. ISBN 90-5199-177-0.
[9] W.J. Dally and C.L. Seitz. Deadlock-free message routing in multiprocessor interconnection
networks. IEEE Transactions on Computers, C-36(5), May 1987.
[10] M.Debbage, M.B.Hill, and D.A.Nicole. Global communications on locally connected message-
passing parallel computers. Concurrency: Practice and Experience, 5(6):491–509, Sept. 1993.
[11] G. Jones. Carefully scheduled selection with ALT. OUG Newsletter, 10:17–23, 1989.
[12] J.M.R. Martin. The Design and Construction of Deadlock-Free Concurrent Systems. D.Phil
<
thesis, University of Buckingham, 1996. Also available from URL:http://www.hensa.ac.uk/
>
parallel/ theory/formal/csp/ .
[13] Formal Systems (Europe) Ltd. FDR user manual and tutorial. Technical Report Version 1.4, 3
Alfred Street, Oxford OX1 4EH., 1994. (Email: [email protected]).
[14] A.W. Roscoe. Model Checking CSP, A Classical Mind. Prentice Hall, 1994.
[15] D.J. Beckett and P.H. Welch. A strict occam design tool. In Proceedings of UK Parallel ’96,
pages 53–69, London, July 1996. BCS PPSIG, Springer-Verlag. ISBN 3-540-76068-7.