123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- .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 5/12 <3nd box.nw, 3nd box.sw>
- line right from 7/12 <2nd box.ne, 2nd box.se> to 7/12 <3nd box.nw, 3nd box.sw>
- line right from 5/12 <4th box.ne, 4th box.se> to 5/12 <5nd box.nw, 5nd box.sw>
- line right from 7/12 <4th box.ne, 4th box.se> to 7/12 <5nd box.nw, 5nd box.sw>
- line down from 5/12 <2nd box.sw, 2nd box.se> to 5/12 <4nd box.nw, 4nd box.ne>
- line down from 7/12 <2nd box.sw, 2nd box.se> to 7/12 <4nd box.nw, 4nd box.ne>
- line down from 5/12 <3rd box.sw, 3rd box.se> to 5/12 <5nd box.nw, 5nd box.ne>
- line down from 7/12 <3rd box.sw, 3rd box.se> to 7/12 <5nd box.nw, 5nd box.ne>
- 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 \f(CWchan_in\fP and \f(CWchan_out\fP. All
- other routines are based on them. The routine \f(CWchan_any\fP only checks if
- there's a value available on a given channel. (It does not read this value!)
- \f(CWC_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 \f(CWc_init\fP, \f(CWchan_in\fP, \f(CWchan_out\fP and \f(CWchan_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 CW
- .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 ``\f(CWopen\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 CW
- 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 CW
- .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
- \f(CWexit\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 CW
- par i = [ base for count ]
- .ft
- .DE
- may be arbitrary expressions. The count in array slices like in
- .DS
- .ft CW
- c ? A[ base for count ]
- .ft
- .DE
- must be a constant expression however, the base is again free.
|