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)