[comp.sys.transputer] occam newsletter 9 deadlock article

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)