occam—a programming language for multiprocessor systems
TRANSCRIPT
Comput. Lang. Vol. 12, No. I, pp. 27-37, 1987 0096-0551/87 $3.00 +0.00 Printed in Great Britain. All rights reserved Copyright ~ 1987 Pergamon Journals Ltd
O C C A M - - A P R O G R A M M I N G L A N G U A G E F O R
M U L T I P R O C E S S O R S Y S T E M S
M. ELIZABETH C. HULL Department of Computing Science, University of Ulster, Shore Road, Newtownabbey,
Co. Antrim BT37 0QB, Northern Ireland
(Receired 29 April 1986; revision received I 1 September 1986)
Al~antct--Tbe features of concurrency provide important concepts for problem solving in a wide range of application areas. Many languages have now been developed to support this approach, with various notations being proposed. Occam is a programming language which supports concurrency using the process as its program structure, and provides synchronous communication between these processes. This paper presents the main features of oocam and illustrates its use through various examples.
Concurrency Oecam Communicating sequential processes Transputer Process
1. I N T R O D U C T I O N
The introduction of concurrency into programming languages, has enabled programmers to provide a new set of solutions to many problems in various application areas. The concept of being able to model a system in a design notation supporting concurrency and then to implement it in a suitable programming language is indeed attractive. One such design notation is Hoare's Communicating Sequential Processes (CSP) [1], which has been well referenced in the literature. The programming language occam [2], which is based on the CSP notation is currently receiving interest. However, the features of the language and the way in which they can be used to solve problems have not been studied widely, due to the small amount of literature available covering programming in the language [2-5].
This paper therefore attempts to provide an overview of occam, with an illustration of its features through small programming examples. It comments on the implementation of programs on the transputer [6].
2. L A N G U A G E O V E R V I E W
The oceam language is based on the concepts of concurrency and communication, and is undoubtedly designed for use by the professional programmer. It is regarded by Inmos as an assembly level language providing a good level of efficiency and performance while offering the reliability of a high-level language. It has many deficiencies that one would not expect to find, and yet it provides a very powerful notation for the development of concurrent systems.
2.1 Sequential processes
The basic unit of an occam program is the process. This simply performs a sequence of actions and then terminates. As the language is oriented towards interactive users, the structures within a process are represented using indentation. As far as variable declarations are concerned, this is achieved using the keyword VAR, but because occam is untyped, a value is one word regardless of its meaning. The following process would therefore declare a variable 'temp' and assign to it the value 100 using the keyword SEQ to identify a sequential process
VAR temp: SEQ
temp: = 100
27
28 M. ELIZASETrl C. HULL
Normally a process will be required to execute not one instruction but a sequence of instructions
VAR tempi, temp2: SEQ
templ : = 100 temp2 : = 200
these being executed in the order in which they appear in the source text. Deterministic choice is represented by a construct using the keyword IF. This is executed by
selecting the first condition that is found to be TRUE in the list, followed by the corresponding statement.
VAR x, flag: IF
X > : 0
flag : = TRUE x < 0
flag : = FALSE
2.2 Parallel processes
Occam provides the facility for actions to take place concurrently rather than sequentially. This is achieved by means of the keyword PAR, and specifies that each component will be executed in parallel until each has terminated. Hence
VAR templ, temp2: PAR
temp 1 : = 100 temp2 : = 200
will allow the assignments to be performed in parallel, and when each has terminated, the construction is said to have terminated.
Obviously parallel activity introduces the need for communication between processes. Such input and output is achieved in occam using channels defined by the keyword CHAN. The channel therefore becomes the central element of a process. A channel, like a variable, is a local declaration of a process. It is set up when the process executes and is deallocated immediately afterwards. The output process
Sink ! expression
sends the value of 'expression' to the channel 'Sink'. The input process
Source ? variable
receives a value from the 'Source' channel and stores it in the variable. In occam communication is synchronous, that is, it can only occur when both the input and
output processes are ready to communicate. An example of the use of channels might be
CHAN Keyboard, Screen: VAR char: SEQ
Keyboard ? char Screen ! char
where a process would receive a character from a 'Keyboard' channel and echo it to a 'Screen' channel. This can be extended by keeping the same input channel, but echoing the character on more than one output channel in parallel. It follows that, at any time, only one process can use a given end of a channel. That is, a maximum of two processes may share a channel.
Occam--A programming language for multiprocessor systems 29
CHAN Keyboard, Screen l, Screen2: VAR char: SEQ
Keyboard ? char PAR
Screenl ! char Screen2 ! char
When programming a sequential piece of code, the parallel construct can prove beneficial in allowing communication and computation to proceed in parallel.
So far we have considered processes to be anonymous, however if required the process can be named with channels provided as parameters
PROC display (CHAN Keyboard, Screen l, Screen2)= VAR char: SEQ
Keyboard ? char PAR
Screenl ! char Screen2 ! char:
Note the final colon which is now required, as this is regarded as a process declaration. With process interaction of this kind, the need for a structure controlling non-determinism is
required. This facility is provided by the alternative, represented by the keyword ALT, which makes use of guarded commands.
ALT Keyboardl ? char
Screen !char Keyboard2 ? char
Screen!char
The alternative will wait until one of the input guards is TRUE, that is, until a corresponding output in another process is possible. The alternative causes one and only one statement to be executed, which one depends on the evaluation of the guard. However one choice must be made. In the above example the alternative will accept the first character received from either keyboard channel and send it to the 'Screen' channel.
The guard itself may consist of a boolean expression together with the input process
ALT morel & Keyboardl ? char
Screen ! char more2 & Keyboard2 ? char
Screen ! char
This example will therefore accept an input from either the 'Keyboardl' or the 'Keyboard2' channel, provided that the value of the corresponding variable morel or more2 is TRUE. In either case the character is output to the 'Screen' channel. This can be extended further for the purpose of echoing characters in a multi-terminal environment, combining parallel sets of sequential statements
PAR VAR char: SEQ
morel & Keyboardl ? char Screenl ! char
VAR char: SEQ
more2 & Keyboard2 ? char Screen2 ! char
30 M. ELIZABETH C. HULL
In some cases there is a need for prioritised alternative processes, which in occam are represented by the PRI ALT construct. This ensures that at any time, a guarded process is selected according to a specified priority ie textual ordering.
WHILE continue PRI ALT
Terminate ? ANY continue : = FALSE
Keyboard ? char Screen ! char
In this case if input is available for both channels, the input from 'Terminate' is selected. When using the PRI ALT construct it is the programmer's responsibility to ensure that the program is logically correct, independent of the assignment of priorities.
2.3 Loops and arrays of processes
Repetitive constructs in occam are represented by while loops and for loops. The while loop is identified with the keyword WHILE followed by an expression and a process. It evaluates the expression and if TRUE executes the process. This is repeatedly executed until the evaluation of the expression is FALSE. For example
SEQ i: = 0 WHILE i < size
i: = i + 1
will repeatedly increment the value of i until it is greater than or equal to size. A non-terminating process can thus be written as follows
WHILE TRUE Source ? char Sink ! char
The traditional 'for' loop is represented in occam by use of a replicator in conjunction with the SEQ construction. Hence the following would output the integers 1 to 20 to the screen channel
SEQ i = [1 FOR 201 Screen ! i
This feature may be extended by using other constructs such as ALT, IF and PAR. For example if it is required to create an array of parallel processes which communicate via a pipeline, then the following could act as such a representation
CHAN channel [n + 1]: PAR i = [0 FOR n]
WHILE TRUE VAR x: SEQ
channel [i] ? x channel [i + 1] ! x
In general the replicator is used to describe collections of processes, the effect of which is to produce a list of processes in which each element is a copy of the process in the replicator. The main use of the parallel replicator is for the construction of arrays of concurrent processes.
Another example would be to represent a process which inputs from any one of an array of channels and then outputs the variable to the 'out' channel
Occam--A programming language for multiprocessor systems 31
WHILE TRUE VAR x:
ALT i = [l FOR lOO] channel [i] ? x
out ! x
2.4 Data declarations and definitions
It has already been shown in this paper that the keywords VAR and CHAN are used to declare variables and channels respectively. Arrays of variables are declared by specifying a size in square brackets
VAR items [50]:
which is indexed as items [0] to items [49]. For string handling and character manipulation, a byte array rather than a word array may be declared
VAR words [BYTE 12]:
with BYTE 0 specifying the length of the string. Constant declarations may be made using the keyword DEF, which also provides the facility
of declaring constant tables
DEF size 100: DEF squares [1,4,9,16]:
An example of these facilities would be to define a constant string and output it character by character to a channel
DEF word = "hello": SEQ i = [1 FOR word [BYTE 0]]
out !word (i]
2.5 The skip and stop processes
The SKIP process is one which performs no action and terminates with no effect. However it is always ready to execute, and is a useful structure if the programmer does not want anything done.
IF linecount = 1
SKIP linecount > 1
SEQ i = [1 FOR line [BYTE 0]] o u t ! l i n e [i]
SKIP may also be used as a guard in an alternative process. The STOP process is similar to SKIP, but it starts and fails to terminate. It is of use when some
unexpected error occurs in a program.
2. 6 Real-time processes
Real-time features can be introduced into occam programs by using the channel TIME. Thus a timer input sets the variable of an input process to a value representing the time. This value is obtained from a free running system clock which changes at regular intervals
TIME ? now
If a variable 'alarm' has been assigned to the time of the system clock plus a particular interval, the following could appear as an input process
TIME ? AFTER alarm
which will delay the input until the value of the clock satisfies the expression.
C.L. 12, | - -C
32 M. ELXZABt'm C. HULL
2. 7 Operators
The normal arithmetic operators of addition, subtraction, multiplication and division are provided together with the comparison, boolean and logical operators. The shift operators permit bit manipulation to be performed.
3. E X A M P L E S P R O G R A M M E D I N O C C A M
This section builds on the overview of occam by illustrating its use through programming examples. The examples chosen have appeared on several occasions with relation to other programming languages and notations [1, 7, 8]. Th~ purpose here is therefore to show the occam solutions, and the reader is invited to compare them with those in other languages.
The examples show clearly the technique of concurrent design through entity recognition. Each resulting occam program, with its process structure, reflects the entities which have been recognised in the problem together with their corresponding operations.
Occam does not provide any facility for text input and output, and it is necessary for the programmer to write routines which will facilitate this. However for the purpose of the simple examples which follow, it is assumed that two channels 'Keyboard' and 'Screen' exist, which will have the effect of inputting from or outputting to an actual terminal. It is assumed that character and integer representation is possible.
Comments in programs are represented by a double hyphen. A comment may occupy a line of its own or follow an occam construct, but in either case terminates at the end of the line.
3.1 Integer division
The process in Program 1 provides a facility for integer division. Two integers are input from channel 'div'; the integer quotient and remainder calculated are output on channel 'ans'. Note the statements which may be performed in parallel within the inner while loop.
- -PROGRAM 1
CHAN div, ans: VAR x, y: WHILE TRUE
VAR rera, quot: SEQ
div ? x;y quot: = 0 rein : ~ x WHILE rem > = y
PAR rem: = rein - y quot: = quot + 1
anstquot;rem
3.2 A Squasher
This well known example replaces every pair of consecutive asterisks of an input character stream, by an upward arrow. As can be seen in Program 2, use is made of the conditional process.
- -PROGRAM 2 ° .
CHAN put, get: DEF asterisk = '**', upwardarrow = '" " VAR c: WHILE TRUE
SEQ put ? c IF
c O asterisk g e t ! ¢
c = asterisk SEQ
Ooeam--A programming language for multiprocessor systems 33
put ? c IF
c 0 asterisk SEQ
get [ asterisk get ! c
c = asterisk get [ upwardarrow
3.3 Bounded buffer
The example in P rogram 3 shows how the keyword P A R can be used to activate three concurrent processes. One which generates items, the second which stores the items in an array and the third process which consumes the items as required. The buffer process makes use o f the alternative construct in selecting which input guard is accepted.
--PROGRAM 3 . °
CHAN send, request, receive: PAR
WHILE TRUE VAR item: SEQ
--generate item send ! :.tern
DEF n = 10: VAR content[n], in, out: SEQ
in : = 0 O U t : = 0
WHILE TRUE ALT
--where '\" represents the MOD operation (in < (out + n)) & send ? content[in\hi
in : - - in+ 1 (out < in) & request ? ANY
SEQ receive ! content[out\n] out : = o u t + 1
WHILE TRUE VAR item: SEQ
request ! A N Y receive ? item -- use item
3.4 Resource scheduler
A scheduler process for a single resource for use by 'n ' users is given in P rogram 4. This requires the declaration o f arrays o f ' request ' and 'release' channels. Use is made o f the replicator process to accept a request f rom any one o f the 'n ' channels. Note that a release opera t ion is only accepted f rom the same channel number as the last request.
-- PROGRAM 4
DEF n = 5: CHAN request[hi, release[n]: WHILE TRUE
VAR i: ALT i = [0 FOR n]
request[il ? ANY release[i] ? ANY
3.5 Extended resource scheduler
In general there will be more than one resource o f a part icular type to be scheduled among the 'n ' users. This will require the availability o f a resource to be stored in an array. P rogram 5 presents
34 M. ELtz~ta 'r~ C. HuLL
the extended resource scheduler. The 'free' array is first initialised and then the process loops, accepting input from any 'request' or 'release' channel.
- - P R O G R A M 5
D E F n = 5, r - - 5: C H A N request[n], release[nl, acquire[hi: V A R free[r], i, j, available: SEQ
available : = r SEQ i = [0 F O R r]
free[i] : = T R U E W H I L E T R U E
A L T A L T i = [0 F O R n]
(available < > 0) & request[i] ? A N Y V A R found: SEQ
PAR found : -- F A L S E j : = 0
W H I L E ( N O T found) A N D ( N O T free[j]) j : = j + l
P A R found : = T R U E free[j] : = F A L S E available : = available - 1 acquire[i] ! j
A L T i = [0 F O R n] release[j] ? j
P A R available : = available + I
free[j] : = T R U E
3.6 Vending machine
Occam can be used to define the behaviour of a vending machine. It is assumed that a user either inserts coins, or pushes a button on the machine to obtain an item. Provided the user has paid the correct amount and there are items in the machine, then it is delivered to the user with change. Otherwise, the machine returns the money inserted. This is demonstrated in Program 6.
This example also demonstrates clearly the facility of multiple output. This is equivalent to a sequence of outputs, the value of each expression being output in turn, in left to right order.
- - P R O G R A M 6 . .
C H A N insert, push, deliver: D E F price = 15, coin = 10: D E F item = T R U E , noth ing = FALSE: VAR items, paid, cash: SEQ
items : = 50 paid : = 0 cash :=0 W H I L E T R U E
A L T insert? A N Y
paid : = paid + coin push ? A N Y
SEQ IF
(items > 0) A N D (paid > -- price) SEQ
deliver ! paid-price; item cash : = cash + price items : ~- items - 1
(items = O) OR (paid < price) deliver ! paid; nothing
paid : -- 0
Oceam--A programming lan6amge for multiprocessor systems 35
3. 7 An alarm clock
P r o g r a m 7 p r e s e n t s a p r o c e s s r e p r e s e n t i n g a n a l a r m c lock . I t e n a b l e s ' n ' u s e r p r o c e s s e s to w a i t
f o r a spec i f ied t i m e i n t e r v a l b e f o r e b e i n g w o k e n u p . A c t u a l t i m e is i n c r e m e n t e d b y a t i ck o p e r a t i o n .
Note the use of the replicator to test each of the elements of the array 'due'.
-- PROGRAM 7 ° °
DEF n = 10: CHAN waiting[n], wakey[n], tick: VAR time, due[n], interval, i: SEQ
time : = 0 i : - I WHILE i < n
due[i] : = - 1 WHILE TRUE
SEQ ALT
ALT i = [0 FOR n] waiting[i] ? interval
due[i] : = time + interval tick ? ANY
time : = time + 1 SEQ i = [(3 FOR n]
IF due[i] = time
PAR wakey[i] I ANY due[i] : -- - 1
TRUE SKIP
3.8 Prime number sieve
The occam program in Program 8 prints in ascending order all primes less than 10000. It makes use of an array of processes, each inputting a prime number from its predecessor and printing it. The process then inputs a stream of numbers passing them on to its successor suppressing any that are multiples of the original prime. This example is used to illustrate the use of process naming in occam.
-- PROGRAM 8 ° °
CHAN Screen AT I: CHAN test[101], printer[102]: DEF EndBuffer = - 3: PRO(3 SIEVE(CHAN left, right, output)=
VAR p, rap, m: SEQ
left ? p output ! p mp : = p WHILE TRUE
SEQ left? m WHILE m > m p
nap : = m p + p IF
m - - r a p SKIP
m < mp right t m:
PROC STARTSIEVE (CHAN start,output)-- VAR n: SEQ
output ! 2 n:=3 WHILE n < 10000
SEQ start ! n n : = n + 2 :
36 M. EL~.,~arrn C. HULL
PROC ENDSIEVE (CHAN finish, output)= VAR n: WHILE TRUE SEQ
finish ? n output [ n:
PROC PRINT = VAR j, n: WHILE T R U E
SEQ ALT j = [0 FOR 102]
printer [j] ? n SEQ
Screen ! n Screen ! EndBuffer:
PAR PAR i = [I FOR 100]
SIEVE ( tcs t [ i - I], test[i], printer[i]) STARTSIEVE (test[0], printer[0l) ENDSIEVE (test[100], printer[101]) PRINT
4. O C C A M A N D T H E T R A N S P U T E R
The transputer architecture consists of programmable VLSI components, integrating as closely as possible a processor unit and its associated memory on one chip measuring 8.7 x 8.9 mm, and containing the equivalent of 200,000 transistor elements. The chip is manufactured using complementary metal oxide--silicon (CMOS) technology using two-level metallisation of alumi- nium and tungsten silicide. The T414 transputer 32-bit processor unit, for example, works at 10 mips and has 2 Kbytes of fast static RAM. The transputer also has communication links which provide point-to-point connection to four more transputers.
In stand-alone mode the transputer can be programmed in any of the conventional languages, however it is used to full advantage in a network. There is a positive relationship between occam and the transputer. Occam can of course be used to program one transputer, with the processor time being shared between the processes, however when used to program a network of transputers each transputer will execute processes and the communication channels between these processes is achieved via the transputer links. Thus it is possible to implement the same occam program on various transputer configurations achieving variations in performance.
5. CONCLUSION
The programming language occam is one of the simplest high-level languages to appear in recent years. Simple in structure, yet far from simple in concept. It provides one of the most convenient notations for expressing concurrent systems, having evolved from its parent--CSP. Getting its name from "Occam's Razor," which implied that nothing but the bare essentials are necessary, it provides a small set of structures for concurrent system design. Processes and channels being the building bricks of such systems.
The drawbacks of occam are highlighted by those who have used modern programming languages, in particular citing the absence of type-checking and recursive procedures. Recursion is not available as occam is intended to be implemented with static storage allocation and a fixed number of processors. However, recursion can be explicitly defined using arrays of processes as with CSP. Occam also provides poor scope control, with often the need to declare variables at too global a level. There is also the temptation for programmers to introduce too much explicit communication between processes. Occam 2 [9] has gone some way to alleviate some of these problems. It introduces types supporting INT, BOOL and a variety of REALS. Since the hardware now supports block transfers, channels have protocols which describe the structure of objects thus allowing messages to be type-checked at compile time. Occam 2 supports separate compilation.
Occarn--A programming language for multiprocessor systems 37
This paper has surveyed the structures and constructs available in the language and has shown how well-understood, yet complex, examples are programmed in occam. It is important to note that much larger systems will benefit from [roplementation in occam, specifically those which relate to real-time. Other areas of application include simulation, computer graphics, computer aided design and process control. All such applications are limited by processor speed and are seen to benefit.
Occam, coupled with the transputer hardware, is therefore seen as a major contribution for the development of concurrent systems. The language itself is not difficult to learn, and the flexibility and the performance of the hardware provide a very acceptable package.
K E F E R E N C E S
1. Hoare C. A. R., Communicating sequential processes. Commun. ACM 21(8), 666--677 (1978). 2. INMOS Lid, Occam Programming Manual. Prentice-Hall, Engelwood Cliffs, N.J. 0984). 3. May D., Occam, Sigplan Not. 18(4), 69-79 (1983). 4. May D. and Taylor R., Occam--an overview. Microprocessors and Microsystems 8(2), 73-79 (1984). 5. Jones G., Programming in Occam. Oxford University Monographs (1985). 6. INMOS Ltd, Transputer Reference Manual (1985). 7. Brinch Hansen P., Distributed processes. Commun. ACM 21(I 1), 934-941 (1978). 8. Welsh J., Lister A. and Salzman E. J., A comparison of two notations for process communication. Proc. Symposium
on Language Design and Programming Methodology, Sydney (1979). 9. May D., Occam 2 Manual. Inmos Ltd (1986).