itcp@ist.CO.UK (News reading a/c for itcp) (10/22/88)
I feel I must respond to Alan Chambers article in the Occam User Group
Newsletter (9).
In tackling the problems of closing down networks of processes by adding
channels whose sole function is to pass a close down message he appears to
be endorsing this solution. It is a bad idea but one quite commonly
found on the occam learning curve. It is a very natural response
to one's first occam programming failing to terminate. The problems with
the solution are:
1. As Alan demonstrates it is very easy to end up deadlocking rather
than terminating. It is also easy to end up with a solution that
avoids deadlock by unwittingly relying on a particular execution
sequence, then when the program is latter distributed across several
processors the program unexpectedly fails to terminate again.
2. The introduction of unecessary channels is a severe handicap to
distributing the program across multiple processors when each
processor has only 4 links.
3. The solution is inefficient, every input on a channel has to become
an ALT on that channel and the closedown channel.
The correct solution is to encode a closedown command in the existing
channel protocols between processes.
If one has to use this technique I have a some observations on Alan's
proffered solution to avoiding deadlock. Firstly the solution's use of
the channel `comm' is redundant, the solution relies on PRI PAR which
may not be available and the solution only works if process B has
a pending output before it will next check the closedown channel
`interrupt.out'.
ALITA and better (as my old maths master used to say) is...
WHILE busy
PRI ALT
interrupt.in ? busy
CHAN OF BOOL comm:
PAR -- get the closedown out before mopping up input
SEQ
interrupt.out ! FALSE -- send closedown to B
comm ! FALSE -- terminate mopping up
BOOL mopping:
SEQ -- mop up until the closedown has been received by B
mopping := TRUE
WHILE mopping
ALT
from.B ? x
SKIP
comm ? mopping
SKIP
... other communications
Alan's article concludes with a long and obscure implementation of
round robin input from an array of channels, that requires use of
the GUY construct to plant in line assembler and relies on a particular
implementation of channels. I worry that it gives the impression that
these things are impossible in occam. The solution he offers has no
advantages over the obvious:
INT round.robin:
SEQ
round.robin := 0
WHILE busy
SEQ
PRI ALT i = 0 FOR choices
input[(i + round.robin) REM choices] ? x
...
round.robin := (round.robin + 1) REM choices
Unfortunately if the channels are of different types I see no alternative to
writing an ALT for each ordering long hand and selecting between them using
`round.robin'.
[Usual disclaimer: this represents only my hastily assembled opinion and
spelling, and not necessarily anyonelse's]
Tom (itcp@uk.co.ist)