|
@@ -0,0 +1,337 @@
|
|
|
+.NH
|
|
|
+Implementation
|
|
|
+.PP
|
|
|
+It is now time to describe the implementation of some of the occam-specific
|
|
|
+features such as channels and \fBNOW\fP. Also the way communication with
|
|
|
+UNIX\(dg is performed must be described.
|
|
|
+.FS
|
|
|
+\(dg UNIX is a trademark of Bell Laboratories
|
|
|
+.FE
|
|
|
+For a thorough description of the library routines to simulate parallelism,
|
|
|
+which are e.g. used by the channel routines and by the \fBPAR\fP construct
|
|
|
+in Appendix B, see [6].
|
|
|
+.NH 2
|
|
|
+Channels
|
|
|
+.PP
|
|
|
+There are currently two types of channels (see Figure 1.) indicated by the type
|
|
|
+field of a channel variable:
|
|
|
+.IP -
|
|
|
+An interprocess communication channel with two additional fields:
|
|
|
+.RS
|
|
|
+.IP -
|
|
|
+A synchronization field to hold the state of an interprocess communication
|
|
|
+channel.
|
|
|
+.IP -
|
|
|
+An integer variable to hold the value to be send.
|
|
|
+.RE
|
|
|
+.IP -
|
|
|
+An outside world communication channel. This is a member of an array of
|
|
|
+channels connected to UNIX files. Its additional fields are:
|
|
|
+.RS
|
|
|
+.IP -
|
|
|
+A flags field holding a readahead flag and a flag that tells if this channel
|
|
|
+variable is currently connected to a file.
|
|
|
+.IP -
|
|
|
+A preread character, if readahead is done.
|
|
|
+.IP -
|
|
|
+An index field to find the corresponding UNIX file.
|
|
|
+.RE
|
|
|
+.LP
|
|
|
+.PS
|
|
|
+box ht 3.0 wid 3.0
|
|
|
+box ht 0.75 wid 0.75 with .nw at 1st box.nw + (0.5, -0.5) "Process 1"
|
|
|
+box ht 0.75 wid 0.75 with .ne at 1st box.ne + (-0.5, -0.5) "Process 2"
|
|
|
+box ht 0.75 wid 0.75 with .sw at 1st box.sw + (0.5, 0.5) "Process 3"
|
|
|
+box ht 0.75 wid 0.75 with .se at 1st box.se + (-0.5, 0.5) "Process 4"
|
|
|
+line right from 5/12 <2nd box.ne, 2nd box.se> to 3rd box
|
|
|
+line right from 7/12 <2nd box.ne, 2nd box.se> to 3rd box
|
|
|
+line right from 5/12 <4th box.ne, 4th box.se> to 5th box
|
|
|
+line right from 7/12 <4th box.ne, 4th box.se> to 5th box
|
|
|
+line down from 5/12 <2nd box.sw, 2nd box.se> to 4th box
|
|
|
+line down from 7/12 <2nd box.sw, 2nd box.se> to 4th box
|
|
|
+line down from 5/12 <3rd box.sw, 3rd box.se> to 5th box
|
|
|
+line down from 7/12 <3rd box.sw, 3rd box.se> to 5th box
|
|
|
+line right 1.0 from 5/12 <5th box.ne, 5th box.se>
|
|
|
+line right 1.0 from 7/12 <5th box.ne, 5th box.se>
|
|
|
+line left 1.0 from 5/12 <2nd box.nw, 2nd box.sw>
|
|
|
+line left 1.0 from 7/12 <2nd box.nw, 2nd box.sw>
|
|
|
+.PE
|
|
|
+.DS C
|
|
|
+\fIFigure 1. Interprocess and outside world communication channels\fP
|
|
|
+.DE
|
|
|
+The basic channel handling is done by \f5chan_in\fP and \f5chan_out\fP. All
|
|
|
+other routines are based on them. The routine \f5chan_any\fP only checks if
|
|
|
+there's a value available on a given channel. (It does not read this value!)
|
|
|
+\f5C_init\fP initializes an array of interprocess communication channels.
|
|
|
+.LP
|
|
|
+The following table shows Occam statements paired with the routines used to
|
|
|
+execute them.
|
|
|
+.TS H
|
|
|
+center, box;
|
|
|
+c | c | c
|
|
|
+lf5 | lf5 | lf5.
|
|
|
+Occam statement Channel handling routine Called as
|
|
|
+=
|
|
|
+.sp 0.5
|
|
|
+.TH
|
|
|
+T{
|
|
|
+.nf
|
|
|
+CHAN c:
|
|
|
+CHAN c[z]:
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_init(c, z)
|
|
|
+chan *c; unsigned z;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_init(&c, 1);
|
|
|
+c_init(&c, z);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+_
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ? v
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+chan_in(v, c)
|
|
|
+long *v; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+chan_in(&v, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ? b[byte i]
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+cbyte_in(b, c)
|
|
|
+char *b; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+cbyte_in(&b[i], &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ? a[i for z]
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_wa_in(a, z, c)
|
|
|
+long *a; unsigned z; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_wa_in(&a[i], z, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ? a[byte i for z]
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_ba_in(a, z, c)
|
|
|
+long *a; unsigned z; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_ba_in(&a[i], z, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+_
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ! v
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+chan_out(v, c)
|
|
|
+long *v; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+chan_out(&v, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ! a[i for z]
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_wa_out(a, z, c)
|
|
|
+long *a; unsigned z; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_wa_out(&a[i], z, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+c ! a[byte i for z]
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_ba_out(a, z, c)
|
|
|
+long *a; unsigned z; chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+c_ba_out(&a[i], z, &c);
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+_
|
|
|
+.sp 0.5
|
|
|
+T{
|
|
|
+.nf
|
|
|
+alt
|
|
|
+ c ? ....
|
|
|
+ ....
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+int chan_any(c)
|
|
|
+chan *c;
|
|
|
+.fi
|
|
|
+T} T{
|
|
|
+.nf
|
|
|
+deadlock=0;
|
|
|
+for(;;) {
|
|
|
+ if (chan_any(&c)) {
|
|
|
+ ....
|
|
|
+ ....
|
|
|
+.fi
|
|
|
+T}
|
|
|
+.sp 0.5
|
|
|
+.TE
|
|
|
+The code of \f5c_init\fP, \f5chan_in\fP, \f5chan_out\fP and \f5chan_any\fP
|
|
|
+can be found in Appendix A.
|
|
|
+.NH 3
|
|
|
+Synchronization on interprocess communication channels
|
|
|
+.PP
|
|
|
+The synchronization field can hold three different values indicating the
|
|
|
+state the channel is in:
|
|
|
+.IP "- \fBC\(ulS\(ulFREE\fP:" 15
|
|
|
+Ground state, channel not in use.
|
|
|
+.IP "- \fBC\(ulS\(ulANY\fP:" 15
|
|
|
+Channel holds a value, the sending process is waiting for an acknowledgement
|
|
|
+about its receipt.
|
|
|
+.IP "- \fBC\(ulS\(ulACK\fP:" 15
|
|
|
+Channel data has been removed by a receiving process, the sending process can
|
|
|
+set the channel free now.
|
|
|
+.LP
|
|
|
+A sending process cannot simply wait until the channel changes state C\(ulS\(ulANY
|
|
|
+to state C\(ulS\(ulFREE before it continues. There is a third state needed to prevent
|
|
|
+a third process from using the channel before our sending process is
|
|
|
+acknowledged. Note, however that it is not allowed to use a channel for input
|
|
|
+or output in more than one parallel process. This is too difficult to check
|
|
|
+in practice, so we tried to smooth it a little.
|
|
|
+.NH 2
|
|
|
+NOW
|
|
|
+.PP
|
|
|
+\fBNOW\fP evaluates to the current time returned by the time(2) system call.
|
|
|
+The code is simply:
|
|
|
+.DS
|
|
|
+.ft 5
|
|
|
+.nf
|
|
|
+ long now()
|
|
|
+ {
|
|
|
+ deadlock=0;
|
|
|
+ return time((long *) 0);
|
|
|
+ }
|
|
|
+.fi
|
|
|
+.ft
|
|
|
+.DE
|
|
|
+The ``deadlock=0'' prevents deadlocks while using the clock.
|
|
|
+.NH 2
|
|
|
+UNIX interface
|
|
|
+.PP
|
|
|
+To handle the communication with the outside world the following channels are
|
|
|
+defined:
|
|
|
+.IP -
|
|
|
+\fBinput\fP, that corresponds with the standard input file,
|
|
|
+.IP -
|
|
|
+\fBoutput\fP, that corresponds with the standard output file,
|
|
|
+.IP -
|
|
|
+\fBerror\fP, that corresponds with the standard error file.
|
|
|
+.IP -
|
|
|
+\fBfile\fP, an array of channels that can be subscripted with an index
|
|
|
+obtained by the builtin named process ``\f5open\fP''. Note that
|
|
|
+\fBinput\fP=\fBfile\fP[0], \fBoutput\fP=\fBfile\fP[1] and
|
|
|
+\fBerror\fP=\fBfile\fP[2].
|
|
|
+.LP
|
|
|
+Builtin named processes to open and close files are defined as
|
|
|
+.DS
|
|
|
+.nf
|
|
|
+.ft 5
|
|
|
+proc open(var index, value name[], mode[]) = ..... :
|
|
|
+proc close(value index) = ..... :
|
|
|
+.fi
|
|
|
+.ft
|
|
|
+.DE
|
|
|
+To open a file `junk', write nonsense onto it, and close it, goes as follows:
|
|
|
+.DS
|
|
|
+.ft 5
|
|
|
+.nf
|
|
|
+ var i:
|
|
|
+ seq
|
|
|
+ open(i, "junk", "w")
|
|
|
+ file[i] ! nonsense
|
|
|
+ close(i)
|
|
|
+.fi
|
|
|
+.ft
|
|
|
+.DE
|
|
|
+Errors opening a file are reported by a negative index, which is the
|
|
|
+negative value of the error number (called \fIerrno\fP in UNIX).
|
|
|
+.LP
|
|
|
+Bytes read from or written onto these channels are taken from occam variables.
|
|
|
+As these variables can hold more than 256 values, some negative values are used
|
|
|
+to control channels. These values are:
|
|
|
+.IP "- \fBEOF\fP" 9
|
|
|
+(-1): Eof from file channel is read as -1.
|
|
|
+.IP "- \fBTEXT\fP" 9
|
|
|
+(-2): A -2 written onto any channel connected to a terminal puts this
|
|
|
+terminal in the normal line oriented mode (i.e. characters typed are echoed
|
|
|
+and lines are buffered before they are read).
|
|
|
+.IP "- \fBRAW\fP" 9
|
|
|
+(-3): A -3 written onto any channel connected to a terminal puts it in raw mode
|
|
|
+(i.e. no echoing of typed characters and no line buffering).
|
|
|
+.LP
|
|
|
+To exit an Occam program, e.g. after an error, a builtin named process
|
|
|
+\f5exit\fP is available that takes an exit code as its argument.
|
|
|
+.NH 2
|
|
|
+Replicators and slices
|
|
|
+.PP
|
|
|
+Both the base and the count of replicators like in
|
|
|
+.DS
|
|
|
+.ft 5
|
|
|
+ par i = [ base for count ]
|
|
|
+.ft
|
|
|
+.DE
|
|
|
+may be arbitrary expressions. The count in array slices like in
|
|
|
+.DS
|
|
|
+.ft 5
|
|
|
+ c ? A[ base for count ]
|
|
|
+.ft
|
|
|
+.DE
|
|
|
+must be a constant expression however, the base is again free.
|