andyr@inmos.com (Andy Rabagliati) (04/19/91)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: fifo.occ fifoc.c inout.occ makefile test1c.c test1o.occ # test2c.c test2o.occ # Wrapped by andyr@inmos-c on Fri Apr 19 08:56:35 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'fifo.occ' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fifo.occ'\" else echo shar: Extracting \"'fifo.occ'\" \(1689 characters\) sed "s/^X//" >'fifo.occ' <<'END_OF_FILE' X--{{{ description of function X-- fifo implements a true fifo - ready to input any time there is room, and X-- ready to output any time there are characters in the buffer. Note that X-- because we have no output ALT, this must be done with two processes. X-- X-- input handles the resource of the buffer itself and the pointers into it, X-- and services requests from two places. First, characters being input from X-- in. Second, requests from the output process for new characters to X-- output. These come in on channel signal. Responses to requests from X-- signal go out on channel more. X-- X-- There is no other way to handle this, given the CSP process model that the X-- Transputer implements. X-- X--}}} XPROC fifo(CHAN OF BYTE in, out) X VAL max IS 256 : -- max buffer size X CHAN OF BOOL signal : X CHAN OF BYTE more : X PAR X --{{{ input process and buffer X [max] BYTE buffer : X INT the.front, back : X BOOL running : X SEQ X the.front, back, running := 0, 0, TRUE X WHILE running OR (the.front <> back) X INT front : X BOOL any : X SEQ X front := (the.front+1) \ max X ALT X (the.front <> back) & signal ? any -- signal for more X SEQ X more ! buffer [back] -- send next X running := buffer[back] <> '~' -- end condition test X back := (back+1) \ max X (front <> back) & in ? buffer[the.front] X the.front := front X --}}} X --{{{ output process X BYTE datum : X SEQ X datum := ' ' X WHILE datum <> '~' X SEQ X signal ! TRUE X more ? datum X out ! datum X --}}} X: END_OF_FILE if test 1689 -ne `wc -c <'fifo.occ'`; then echo shar: \"'fifo.occ'\" unpacked with wrong size! fi # end of 'fifo.occ' fi if test -f 'fifoc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'fifoc.c'\" else echo shar: Extracting \"'fifoc.c'\" \(2888 characters\) sed "s/^X//" >'fifoc.c' <<'END_OF_FILE' X#include <process.h> X#define MAX 256 X#define NULL ((void *) 0) X X /* X * fifo implements a true fifo - ready to input any time there is room, and X * ready to output any time there are characters in the buffer. Note that X * because we have no output ALT, this must be done with two processes. X * X * input_p handles the resource of the buffer itself and the pointers into it, X * and services requests from two places. First, characters being input from X * *in. Second, requests from the process output_p for new characters to X * output. These come in on channel *signal. Responses to requests from X * signal go out on channel *more. X * X * There is no other way to handle this, given the CSP process model that the X * Transputer implements. X * X * output_p simply requests characters, then outputs them on channel *out. X * X * Please note the way guards on ALTs are implemented. There are slightly more X * simple methods, but this is a very general mechanism. If the guard is X * false, we put the channel always_empty in the alt list. Having an empty X * channel means that the index returned by the ProcAltList function always X * corresponds to the same input being ready. Very handy. X * X * Though in this case we will only be using always_empty in one place in the X * alt list, it can be put in many places. Thus if we have a 100-way guarded X * ALT, we only need one always_empty channel. X * X */ X Xvoid input_p(Process * parent, X Channel * in, Channel * signal, Channel * more) X{ X Channel always_empty; /* remember to use & in refs */ X Channel *altlist[3]; X char buffer[MAX], lastchar = ' '; X int the_front = 0, back = 0; X ChanInit(&always_empty); X altlist[2] = NULL; /* terminator for ProcAltList */ X X while (lastchar != '~') X { X /* useful incremented version of the_front */ X int front = (the_front + 1) % MAX; X altlist[0] = (the_front != back) ? signal : &always_empty; X altlist[1] = (front != back) ? in : &always_empty; X switch (ProcAltList(altlist)) X { X case 0: X ChanInChar(signal); /* must input signal !! */ X ChanOutChar(more, lastchar = buffer[back++]); X back = back % MAX; X break; X case 1: X buffer[the_front] = ChanInChar(in); X the_front = front; X break; X } X } X} X Xvoid output_p(Process * parent, X Channel * out, Channel * signal, Channel * more) X{ X char c = ' '; X while (c != '~') X { X ChanOutChar(signal, '*'); /* anything */ X ChanOutChar(out, c = ChanInChar(more)); X } X} X Xvoid fifo(Process * parent, Channel * in, Channel * out) X{ X Channel signal, more; X ChanInit(&signal); X ChanInit(&more); X ProcPar( X ProcAlloc(input_p, 100, 3, in, &signal, &more), X ProcAlloc(output_p, 100, 3, out, &signal, &more), X NULL ); X} END_OF_FILE if test 2888 -ne `wc -c <'fifoc.c'`; then echo shar: \"'fifoc.c'\" unpacked with wrong size! fi # end of 'fifoc.c' fi if test -f 'inout.occ' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'inout.occ'\" else echo shar: Extracting \"'inout.occ'\" \(2002 characters\) sed "s/^X//" >'inout.occ' <<'END_OF_FILE' X-- The iserver routines can easily be replaced by similar ones in the hostio X-- library. I just like to know exactly what is going on - this way nothing X-- goes on the Transputer that I dont know about. X-- This applies to write.char, pollkey, and so.exit. X XPROTOCOL SP IS INT16::[]BYTE : X--{{{ PROC inout(CHAN OF SP fs, ts, CHAN OF BYTE out, in) XPROC inout(CHAN OF SP fs, ts, CHAN OF BYTE out, in) X -- routines similar to these are in hostio.lib X --{{{ PROC write.char (VAL BYTE char) X PROC write.char (VAL BYTE char) X SEQ X ts ! 8(INT16)::[24(BYTE), -- length, FPutBlock X 1(BYTE), 0(BYTE), 0(BYTE), 0(BYTE), -- StreamId = 1 X 1(BYTE), 0(BYTE), -- INT16 len = 1 X char ] X INT16 len : X [8]BYTE packet : X fs ? len::packet X : X --}}} X --{{{ PROC pollkey(BYTE char, BYTE result) X PROC pollkey(BYTE char, BYTE result) X INT16 len : X [8]BYTE packet : X SEQ X ts ! 8(INT16)::[31(BYTE), -- length, Pollkey X 'x','x','x','x','x','x','x'] -- padding to 8 bytes X fs ? len::packet -- read result X char, result := packet[1], packet[0] X : X --}}} X BYTE char : X SEQ X char := ' ' X WHILE char <> '~' X TIMER TIME : X INT now : X SEQ X TIME ? now X ALT X in ? char X write.char(char) X TIME ? AFTER now PLUS 156 -- 1/100 sec X BYTE key, result : X SEQ X pollkey(key, result) X IF X result = 0(BYTE) X out ! (BYTE key) X TRUE X SKIP X: X--}}} X--{{{ PROC so.exit(CHAN OF SP fs, ts) XPROC so.exit(CHAN OF SP fs, ts) X SEQ X ts ! 8(INT16)::[35(BYTE), -- length, Exit X #FF(BYTE), #C9(BYTE), #9A(BYTE), #3B(BYTE), -- Success 999999999 X 'x','x','x'] -- padding X INT16 len : X [8]BYTE packet : X fs ? len::packet X: X--}}} END_OF_FILE if test 2002 -ne `wc -c <'inout.occ'`; then echo shar: \"'inout.occ'\" unpacked with wrong size! fi # end of 'inout.occ' fi if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(1423 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' XOCCOPT= /y /t8 XLINKOPT= /y /t8 XCONFOPT= XOCONFOPT= XCOLLECTOPT= /t XCOPT= /t8 X Xtest2c: test2c.btl X iserver /se /sb test2c.btl X Xtest2c.btl: test2c.lku X icollect $(COLLECTOPT) test2c.lku X Xtest2c.lku: test2c.tco fifoc.tco X ilink $(LINKOPT) test2c.tco fifoc.tco libc.lib centry.lib /me C.ENTRY X Xtest2c.tco: test2c.c X icc $(COPT) test2c.c X Xfifoc.tco: fifoc.c X icc $(COPT) fifoc.c X Xtest1c: test1c.btl X iserver /se /sb test1c.btl X Xtest1c.btl: test1c.lku X icollect $(COLLECTOPT) test1c.lku X Xtest1c.lku: test1c.tco X ilink $(LINKOPT) test1c.tco libc.lib centry.lib /me C.ENTRY X Xtest1c.tco: test1c.c X icc $(COPT) test1c.c X Xtest2o: test2o.btl X iserver /se /sb test2o.btl X Xtest2o.btl: test2o.lku X icollect $(COLLECTOPT) test2o.lku X Xtest2o.lku: test2o.tco inout.tco fifo.tco X ilink $(LINKOPT) test2o.tco inout.tco fifo.tco X Xtest2o.tco: test2o.occ inout.tco fifo.tco X oc $(OCCOPT) test2o.occ X Xtest1o: test1o.btl X iserver /se /sb test1o.btl X Xtest1o.btl: test1o.lku X icollect $(COLLECTOPT) test1o.lku X Xtest1o.lku: test1o.tco X ilink $(LINKOPT) test1o.tco inout.tco X Xtest1o.tco: test1o.occ inout.tco X oc $(OCCOPT) test1o.occ X Xinout.tco: inout.occ X oc $(OCCOPT) inout.occ X Xfifo.tco: fifo.occ X oc $(OCCOPT) fifo.occ X END_OF_FILE if test 1423 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi if test -f 'test1c.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test1c.c'\" else echo shar: Extracting \"'test1c.c'\" \(1905 characters\) sed "s/^X//" >'test1c.c' <<'END_OF_FILE' X#include <process.h> X#include <stdio.h> X#include <iocntrl.h> X X#define MAX 100 X Xvoid buf (Process *parent, Channel *in, Channel *out) { X char c = ' '; X while (c!='~') X ChanOutChar(out, c=ChanInChar(in)); X} X Xvoid buffer (Process *parent, Channel *in, Channel *out) { X Channel pipe[MAX]; /* we are declaring the channels themselves, X * so remember to use & address-of */ X Process *list[MAX+2]; /* will be MAX+1 processes */ X int i; X X for (i=0; i < (MAX-1); i++) { X ChanInit(&pipe[i]); /* clear channel */ X list[i] = ProcAlloc(buf, 80, 2, &pipe[i], &pipe[i+1]); X /* 80 bytes seems to be enough */ X } X ChanInit(&pipe[MAX-1]); /* last pipe - not hit by loop above */ X X list[MAX-1] = ProcAlloc(buf, 80, 2, in, &pipe[0]); X list[MAX] = ProcAlloc(buf, 80, 2, &pipe[MAX-1], out); X list[MAX+1] = NULL; /* end of list for ProcParList */ X X ProcParList(list); X} X Xvoid inout(Process *parent, Channel *out, Channel *in) { X int key; X char c = ' '; X while (c!='~') { X switch (ProcTimerAlt(ProcTimePlus(ProcTime(), 156), in, NULL)) { X case -1: X key = pollkey(); X if (key != -1) X ChanOutChar(out, (char) key); X break; X case 0: X putchar(c = ChanInChar(in)); X fflush(stdout); X break; X } X } X} X Xint main(void) { X Channel to_buf, from_buf; /* we are declaring the channels themselves, X * so remember to use & address-of */ X ChanInit(&to_buf); X ChanInit(&from_buf); X ProcPar( X ProcAlloc(inout, 4096, 2, &to_buf, &from_buf), X ProcAlloc(buffer, 4096, 2, &to_buf, &from_buf), NULL ); X X return (999999999); /* success */ X} X END_OF_FILE if test 1905 -ne `wc -c <'test1c.c'`; then echo shar: \"'test1c.c'\" unpacked with wrong size! fi # end of 'test1c.c' fi if test -f 'test1o.occ' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test1o.occ'\" else echo shar: Extracting \"'test1o.occ'\" \(458 characters\) sed "s/^X//" >'test1o.occ' <<'END_OF_FILE' XPROTOCOL SP IS INT16::[]BYTE : X#USE "inout.tco" XPROC exercise1(CHAN OF SP fs, ts, []INT memory) X SEQ X VAL MAX IS 10 : X [MAX+1]CHAN OF BYTE pipe : X PAR X inout(fs, ts, pipe[0], pipe[MAX]) X PAR i = 0 FOR MAX X --{{{ little buffer processes X BYTE char : X SEQ X char := ' ' X WHILE char <> '~' X SEQ X pipe[i] ? char X pipe[i+1] ! char X --}}} X so.exit(fs, ts) X: END_OF_FILE if test 458 -ne `wc -c <'test1o.occ'`; then echo shar: \"'test1o.occ'\" unpacked with wrong size! fi # end of 'test1o.occ' fi if test -f 'test2c.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test2c.c'\" else echo shar: Extracting \"'test2c.c'\" \(1301 characters\) sed "s/^X//" >'test2c.c' <<'END_OF_FILE' X#include <process.h> X#include <stdio.h> X#include <iocntrl.h> X Xvoid fifo(Process *, Channel *, Channel *, Channel *); X X /* X * inout is functionally equivalent to two parallel processes, one taking X * keys from the keyboard and outputting them to *out, the other reading X * characters from *in and writing them to the screen. It is in fact X * implemented as an ALT, because both pseudo-processes need both iserver X * channels. X */ X Xvoid inout(Process * parent, Channel * out, Channel * in) X{ X int key; X char c = ' '; X while (c != '~') X { X switch (ProcTimerAlt(ProcTimePlus(ProcTime(), 156), in, NULL)) X { X case -1: /* timeout - poll keyboard */ X key = pollkey(); X if (key != -1) X ChanOutChar(out, (char) key); X break; X case 0: /* in is ready - read it */ X putchar(c = ChanInChar(in)); X fflush(stdout); X break; X } X } X} X Xint main(void) X{ X Channel to_buf, from_buf; /* we are declaring the channels X * themselves, so remember to use & X * address-of */ X ChanInit(&to_buf); X ChanInit(&from_buf); X ProcPar( X ProcAlloc(inout, 4096, 2, &to_buf, &from_buf), X ProcAlloc(fifo, 4096, 2, &to_buf, &from_buf), X NULL ); X X return (999999999); /* success */ X} END_OF_FILE if test 1301 -ne `wc -c <'test2c.c'`; then echo shar: \"'test2c.c'\" unpacked with wrong size! fi # end of 'test2c.c' fi if test -f 'test2o.occ' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test2o.occ'\" else echo shar: Extracting \"'test2o.occ'\" \(251 characters\) sed "s/^X//" >'test2o.occ' <<'END_OF_FILE' XPROTOCOL SP IS INT16::[]BYTE : X#USE "inout.tco" X#USE "fifo.tco" XPROC exercise2(CHAN OF SP fs, ts, []INT memory) X SEQ X CHAN OF BYTE to.buf, from.buf : X PAR X inout(fs, ts, to.buf, from.buf) X fifo(to.buf, from.buf) X so.exit(fs, ts) X: END_OF_FILE if test 251 -ne `wc -c <'test2o.occ'`; then echo shar: \"'test2o.occ'\" unpacked with wrong size! fi # end of 'test2o.occ' fi echo shar: End of shell archive. exit 0