Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-11 - 43,50531/ipcf.rnm
There are 2 other files named ipcf.rnm in the archive. Click here to see a list.
.title The Inter-Process Communication Facility
.subtitle Overview of the system
.rm 72
.para
The Inter-Process Communication Facility (IPCF) allows jobs to
communicate with one another by sending and receiving packets of information.
Jobs identify each other by means of Process Identifiers (PIDs).  A job may acquire
a PID by sending a message via IPCF to a system process, [SYSTEM]INFO,
giving a name, and requesting that INFO assign a PID
to that name.  PIDs may be acquired that will be dropped on a RESET UUO
(usually executed at the start of a program), or
not until LOGOUT.  A job may find the PID of another job by requesting INFO
to return the PID corresponding to a name.  Thus, all that needs to be known
for inter-job communication is what names the various jobs will use to acquire
their PIDs.
.para
A name may be be ASCII string with up to 29 characters, with a few restrictions:
.skip 1
	text
.break
	[<brackettext>]text
.BREAK
	text[<brackettext>]
.skip 1
where <brackettext> may be:
.skip 1
	SYSTEM		(if you are privileged)
.break
or:	<proj>,<prog>
.skip 1
where <proj> and <prog> may be your project or programmer number, respectively,
or may be the string 'ALL'  (including the apostrophes).
.para
Once the PID of another job is known, you may send a message to it.  Similarily,
 once another job knows your PID, it can send messages to you.
A message may be either a small block of up to 10 words (this is a monitor
assembly parameter.  Look at word 0 of GETTAB table 77 to see what the
limit is for your monitor), or it may be
a full page of memory (512 words).  A user must have virtual memory privileges
to send or receive a page-mode message.
.para
For each job, the monitor maintains both a send queue and a receive
queue.  A message is in your receive
queue if you have not received it.  A message is in your send queue
if the job to whom you sent the message has not received it yet.  Your
default receive quota is 5; i.e. you can have up to 5 unread messages at a
time.  Your default send quota is 2; i.e. you may have sent up to 2 unreceived
messages at any time.  If these quotas are insufficient, they can be changed
by your system administrator.
.para
It is possible to use the software interrupt system (PSI)
to trap IPCF receives. You may also use the HIBER UUO to sleep until a
packet arrives.
.para
A package of routines is supplied to do any IPCF function.  Versions of this
package are provided that may be called by FORTRAN, SAIL, BLISS, PASCAL, or
MACLISP.
.page.para
The following routines are provided:
.skip 1
.lm 24.indent -16
IPCINF##########Make a request of [SYSTEM]INFO.  At your option,
control may return immediately (you may receive INFO's answer later, using IPCANS), or IPCINF will wait for the answer,
receiving and retaining any intervening messages.
.skip 1.i -16
IPCCON##########Make a request of [SYSTEM]IPCC.  Like IPCINF in that the routine
will either return immediately or wait for the answer.
.skip 1.i -16
IPCFUN##########If first packet is from INFO or IPCC, return the function.
.skip 1.i -16
IPCANS##########If IPCINF or IPCCON did not wait for an answer and the answer
is at the front of the queue, complete the request.
.skip 1.i -16
IPCQER##########Query the state of your receive queue and return information
on the first message.
.skip 1.i -16
IPCWQR##########Same as IPCQER, but wait until a message arrives.
.skip 1.i -16
IPCSND##########Send a page-mode message.  The user does not have to
select a page and pack it with information - IPCSND will do this. The
user merely specifies a variable number of blocks of data, giving
size and location for each, and IPCSND will send as many page-mode messages
as necessary.
.skip 1.i -16
IPCRCV##########Receive either a small or a page mode message, and unpack
it into a variable number of blocks of data, specified as in IPCSND.  The
message may be retained, allowing a reread capability.  To facilitate this,
the offset into the message to start reading data from may be specified
as a parameter.
.skip 1.i -16
IPCSML##########Send a small message.
.skip 1.i -16
IPCGET##########Return global IPCF GETTAB info.
.skip 1.i -16
IPCGTJ##########Return per-job IPCF GETTAB info.
.skip 1.i -16
IPCDIS##########Discard the first message in your receive queue.
.skip 1.i -16
IPCERR##########Type a message identifying IPCF errors.
.skip 1.i-16
IPCINI##########(BLISS and PASCAL only)  Initialize core management.
.lm 0.page.para
A typical use of these routines could be as follows:
.para
BLISS or PASCAL programs would
call IPCINI as part of their initialization.  Then, IPCINF would be
used to obtain a PID for a name (function -3).  Then, IPCINF would be used to find the
PIDS of other jobs, specifying the names they will use (function -1). At this point,
IPCSND could be used to send messages to any cooperating jobs, and IPCWQR
used to await their reply. When IPCWQR wakes up and returns to it's caller,
the message may be received and read (and reread, if desired) by using
IPCRCV, or discarded by using IPCDIS. IPCSND could be used again...(etc.)
.para
A program that will never initiate communications, but will wait for other jobs
to contact it, may omit using IPCINF to find the PIDs of cooperating
jobs--the PID is returned as a parameter by IPCWQR or IPCRCV.  Such a program
would obviously not use IPCSND until at least one IPCRCV had been done, thereby establishing
the existence of a cooperating job.
.page.subtitle How to access routines
.para
Five versions of these routines are available:
.para
REL:IPCFOR.REL uses the FORTRAN-10 calling convention and the  FUNCT_. interface to the runtime system to allocate
any pages that must be saved between routine calls. Thus, FORTRAN-10, COBOL,
and ALGOL may use this package.
.para
AIL:IPCSAI.REL uses the SAIL calling convention and calls on SAIL's runtime system
to allocate core and deal with strings.  AIL:IPCF.HDR may be 'REQUIRED' by SAIL
programs to provide the necessary external declarations.
.para
REL:IPCBLI.REL uses the BLISS-10 calling convention and allocates core at _.JBFF.
.para
REL:IPCPAS.REL uses the FORTRAN-10 calling convention, but allocates core at
_.JBFF, not relying on any runtime-support.  This is useable from PASCAL if
you declare the routines to be external FORTRAN procedures in your PASCAL
program.  Note that this file is essentially what used to be IPCBLI, when
BLISS programs went through the FCALL routine to call the FORTRAN-10
version of the IPCF package.  Old BLISS programs using FCALL should either
convert to IPCBLI, or load with IPCPAS instead.
.para
COM:IPCF.FAS is a FASL file that may be FASLOAD'ed by MACLISP jobs.
.page
^&How to call routines from FORTRAN-10\&:
.skip 1
In your program:
.nofill.skip 1
	INTEGER ARG1,ARG2,...
	    .
	    .
	    .
	CALL IPC???(ARG1,ARG2,...)
.fill
.skip 1
To load:
.skip 1
	.LOAD MAIN.FOR,REL:IPCFOR.REL/SEARCH
.skip 3
^&How to call the routines from SAIL\&:
.skip 1
In your program:
.nofill.skip 1
	REQUIRE "AIL:IPCF.HDR"	SOURCE!FILE;
	    .
	    .
	    .
	IPC???(ARG1,ARG2,...);
.fill.skip 1
To load:
.skip 1
	.LOAD MAIN.SAI
.skip 3
^&How to use the IPCF routines from PASCAL\&:
.skip 1
In your program:
.skip 1.nofill
	PROCEDURE IPC???(ARG1,VAR ARG2,...);FORTRAN;
		(*assuming ARG1 is a value parameter and ARG2 is a
		  reference parameter*)
	    .
	    .
	    .
	IPC???(ARG1,ARG2,...);
.fill.skip 1
To load:
.skip 1
	.LOAD MAIN.PAS,REL:IPCPAS.REL
.page
^&How to call routines from BLISS\&:
.skip 1
In your program:
.nofill.skip 1
	EXTERNAL IPC???;
	    .
	    .
	    .
	IPC???(PLIT ARG1,	%assuming first arg is a constant%
	       ARG2,		%assuming next arg is a reference var%
		  .
		  .
		  .
	       ARGn)		%last arg of IPC???%
.fill.skip 1
To load:
.skip 1
	.LOAD MAIN.BLI,REL:IPCBLI.REL/SEARCH
.skip 3
If you want to use the FCALL routine for some reason (perhaps to take advantage of the
variable number of arguments the FORTRAN version allows), place in your
program:
.nofill.skip 1
	EXTERNAL IPC???,FCALL;
	    .
	    .
	    .
	FCALL(IPC???,		%first arg is name of routine%
	      (PLIT ARG1),	%assuming second arg is a const%
	      ARG2,		%assuming next arg is a variable%
		  .
		  .
		  .
	      ARGN,		%last arg of IPC???%
	      N+1);		%number of preceding arguments%
.fill.skip 1
To load:
.skip 1
	.LOAD MAIN.BLI,/SEARCH REL:IPCBLI.REL,REL:FCAL10.REL
.page
^&How to use IPCF functions in MACLISP\&:
.skip 1
In your program:
.skip 1.nofill
	(SETQ ERROR (IPC??? ARG1 'ARG2 ...))
		;assumes ARG1 is a value parameter and ARG2 is a
		;reference parameter.  Also assumes that error code
		;is returned as value of function
.fill.skip 1
To load:
.skip 1
	(FASLOAD IPCF FAS COM)
.subtitle Description of the routines
.page
The general call of an IPCF routine is described like this:
.skip 1.nofill
	ROUTINENAME(mode ARG1,		;comment about ARG1
		    mode ARG2,		;comment about ARG2
			.
			.
			.
		    mode ARGn);		;comment about ARGn
.fill.skip 1
Mode describes the type of the argument:
.lm 12.skip 1.i-12
INTEGER#####This is an INTEGER (FIXNUM, in MACLISP) parameter that is passed by value.  Ie,
no value is returned in this parameter, so it may be a constant.
.skip 1
FORTRAN, SAIL, or PASCAL:
.i 5
5
.i 5
N	;where N is an integer variable
.i 5
16*M+1
.i 5
A[5]
.skip
BLISS:
.i 5
5
.i 5
_.N	;where N is an integer variable
.i 5
_.A[4]
.skip
MACLISP:
.i 5
5
.i 5
FOO	;where FOO has a FIXNUM as it's VALUE property
.i 5
(A 6)	;where A is a FIXNUM array
.skip 1.i-12
REF#INTEGER#This is an INTEGER (FIXNUM, in MACLISP) parameter passed by reference--a
value will be returned in this parameter, so something that evaluates to
a constant may not be used.
.skip 1
FORTRAN, SAIL, PASCAL, or BLISS:
.i 5
N	;where N is an integer variable
.i 5
A[4]	;where A is an integer array
.skip 1
MACLISP:
.i 5
'N	;a (SET 'N value)  will be done
.skip 1.i -12
REF#STRING##This is a string parameter passed by reference--a value will be
returned in it.  FORTRAN, BLISS, and PASCAL do not have strings, so arrays must
be used:
.skip 1
FORTRAN:
.i 5
INTEGER A(6)
.i 5
A(1)='FIRST'
.i 5
A(2)='SECON'
.i 9
_.
.i 9
_.
.break
or:
.i 5
DOUBLE PRECISION A
.i 5
A='TWO WORDS '
.skip 1
BLISS:
.i 5
LOCAL A[1:6];
.i 5
A[1]__'FIRST';
.i 9
_.
.i 5
_.
.skip 1
PASCAL:
.i 5
VAR A:PACKED ARRAY [1..30] OF CHAR;
.i 5
A[1]:="T"; A[2]:="H";
.i 5
_.
.i 5
_.
.break
or:
.i 5
VAR A:ARRAY [1..6] OF PACKED ARRAY [1..5] OF CHAR;
.i 5
A[1]:="FIRST";
.i 5
A[2]:="SECON";
.i 5
A[3][2]:="C";
.i 5
_.
.i 5
_.
.break
or however you wish to access 30 characters in 6 consecutive words.
.skip 1
SAIL:
.i 5
STRING S;
.i 5
S__"this is a string";
.skip 1
MACLISP:
.i 5
any atom may be used.
.i 5
(SETQ A 'THIS/ IS/ A/ STRING)
.break
or:
.i 5
(SETQ A '|THIS IS A STRING|)
.break
using the broken vertical bar (ASCII code 174 octal) as a delimiter.
.skip 2
Warning!  FORTRAN will blank-fill hollerith constants.  Therefore, if A is
double precision,
.i 5
A='ABCD'
.break
really assigns 'ABCD######'  to variable A.  Similarily,
.i 5
IF (A .EQ. 'ABCD') ...
.break
really compares A against 'ABCD######'.  For this reason, the IPCINF call that
assigns a PID based on the name of the program you are running, will blank-fill
the two word quantity, in the version for all languages.
.skip 1.i -12
STRING######This is a string parameter passed by value--a value will not be returned.
The version of the IPCF routines for FORTRAN, SAIL, BLISS, and PASCAL do
not use these--all strings are passed by reference, whether or not a value
is returned.
.skip 1
MACLISP:
.i 5
'STRING		;to pass the string "STRING"
.i 5
FOO		;if previously was done:
.i 5
		;	(SETQ FOO 'SOMESTRING)
.skip 1.i -12
REF#INTEGER#ARRAY#[LOW:HIGH]####This is an integer array with specified bounds,
passed by reference.
.skip 1
FORTRAN:
.i 5
INTEGER A(100)
.i 5
CALL IPC???(...,A,...)
.skip 1
BLISS:
.i 5
LOCAL A[1:100];
.i 5
IPC???(...,A,...);
.skip 1
SAIL:
.i 5
INTEGER ARRAY A[1:100];
.i 5
IPC???(...,A,...);
.skip 1
PASCAL:
.i 5
VAR A:ARRAY [1..100] OF INTEGER;
.i 5
IPC???(...,A,...);
.skip 1
MACLISP:
.i 5
(ARRAY A FIXNUM 1000)
.i 5
(IPC??? ... 'A ... )
.lm 0.skip 3
Note for MACLISP users:
.para
All the routines (except IPCERR, IPCGET, and IPCGTJ) are described as returning an error code in the
first parameter:  eg,
.i 8
IPC???(REF INTEGER ERROR, ...)
.skip 1
This is not true for the MACLISP callable version--the error is returned as
the value of the function (with NIL meaning no error).  Therefore, instead of:
.i 8
IPC???(ERROR,other args)
.break
do:
.i 8
(SETQ ERROR (IPC??? other args))
.subtitle Description of the routines--IPCINF
.page
The IPCINF routine is used to make a request to [SYSTEM]INFO.  It sets
up some preliminary information, checks the validity of the function,
ans dispatches to the proper code to handle that particular function.
.para
Note that I wrote these routines in the fall of 1974;  at that time, the
only languages that needed to call these routines were FORTRAN and MACLISP
(and BLISS, calling the FORTRAN version through FCALL).  None of these
languages do compile-time type checking, and each of them allows a
variable number of arguments.  At the time, it seemed like a good idea to
provide one IPCINF routine with differing arguments to make all calls on
[SYSTEM]INFO, rather than provide 7 routines, one for each function.
Now, however,  with more knowledge of computer science, and the need to have
SAIL and PASCAL  call these routines, it seems like it was a bad idea.  Of
course, you can easily write your own 7 routines, each of which calls IPCINF
with the appropriate function and parameters.
.skip 1
General call:
.skip 1.nofill
	IPCINF(REF INTEGER ERROR,	;error code returned here
	       INTEGER FUNCT,		;IPCINF function
	       INTEGER CODE,		;code to identify this request
	       INTEGER DUPPID,		;pid to receive copy of answer
	       REF INTEGER PID,		;PID or job #
	       INTEGER FLAG,		;flag
	       REF STRING NAME);	;name
.fill
ERROR is returned 0 (or NIL) if no error occurred, otherwise it is an
error code.  ( >0 is an IPCF error, <0 is some other error).
.break
FUNCT is the function that you are requesting of INFO.  The magnitude must
be between 1 and 7.  If it is negative, IPCINF will wait until the answer from
INFO arrives, receiving and saving any messages that arrive before.  If it
is positive, IPCINF will send the message to INFO and return immediately.
.break
CODE is an 18 bit quantity to allow the user to associate an answer with
a request.
.break
DUPPID is the PID of the user to receive a duplicate copy of the reply, or is 0.
([SYSTEM]INFO will send the copy, not IPCINF).
.break
PID is either an argument, or is returned.  Unfortunately,  except in the MACLISP
version, this parameter must always be a REF INTEGER;  in MACLISP, it is
only a REF INTEGER in functions 1, 3, and 4.
.break
FLAG determines the handling of NAME, in the FORTRAN, PASCAL, and BLISS versions:
.break
	If NAME is an argument, and
.lm24.i-8
FLAG < 0, then NAME is a double precision ASCII string.
.i -8
FLAG = 0, then IPCINF must make a double precision, blank-filled ASCII string
from the program name.
.i -8
FLAG > 0, then name is a 6 word ASCII string.  Only the first 29 characters
will be sent.
.skip 1.i-16
If NAME is returned, and:
.i -8
FLAG <= 0, then NAME is assumed to be double precision, and only the first
10 characters of the name will be returned.
.i -8
FLAG > 0, then NAME is assumed to be a 6 word array, and all 29 characters
of the name will be returned.
.skip 1.lm 0
The SAIL and MACLISP versions only care if flag = 0 or not.  Any supplied or
returned string will be a standard SAIL string (for SAIL), or quoted string
(for MACLISP).  Note also that the seventh parameter is a REF string, even though
only 1 of the 4 functions that require this parameter returns a value.
The MACLISP version is smarter--it requires a REF STRING parameter only for
function 2; functions 1, 3, and 4 require a STRING parameter.
.skip 1
The functions that IPCINF will request INFO to perform are:
.lm 16.i -16
1	CALL IPCINF(ERROR,1,CODE,DUPPID,PID,FLAG,NAME)
.break
Return the PID corresponding to the name
.i -16
2	CALL IPCINF(ERROR,2,CODE,DUPPID,PID,FLAG,NAME)
.break
Return the name corresponding to the PID
.i -16
3	CALL IPCINF(ERROR,3,CODE,DUPPID,PID,FLAG,NAME)
.break
Assign the name and return a PID to be dropped on RESET.
.i -16
4	CALL IPCINF(ERROR,4,CODE,DUPPID,PID,FLAG,NAME)
.break
Assign the name and return a PID to be dropped on LOGOUT.
.lm 0.skip 1
For the following 3 functions, If FLAG is non-0, privileges will be invoked.
If FLAG is not present, or is present and is 0, privileges will not be invoked.
For the SAIL and BLISS versions, not only must FLAG be present, but a dummy
NAME must be present too (the routine has 7 parameters).
.lm 16.i -16
5	CALL IPCINF(ERROR,5,CODE,DUPPID,PID,FLAG)
.break
Drop the specified PID.
.lm 0.skip 1
For the following two functions, JOB must be a job number and not a PID.
.lm 16.i -16
6	CALL IPCINF(ERROR,6,CODE,DUPPID,JOB,FLAG)
.break
Drop all PIDS for the specified job that were signed out until RESET  (using
IPCINF function 3).
.i -16
7	CALL IPCINF(ERROR,7,CODE,DUPPID,JOB,FLAG)
.break
Drop all PIDs for the specified job, even those assigned with function 4.
.subtitle Description of the routines--IPCFUN
.lm 0.page
The IPCFUN routine will check if the first packet in the queue is from
[SYSTEM]INFO or [SYSTEM]IPCC.  If so, it will read in and retain the message,
returning the code and function from the first word.  If not, error -5
will be returned.
.skip 1
General call:
.break.nofill
	IPCFUN(	REF INTEGER ERROR,	;error code
		REF INTEGER FUNCT,	;function
		REF INTEGER CODE,	;18 bit code
		REF INTEGER WHO);	;who message is from
.fill.skip 1
Who is returned to indicate who the message is from:
.i 8
WHO=1	;[SYSTEM]IPCC
.i 8
WHO=2	;public [SYSTEM]INFO
.i 8
WHO=3	;private [SYSTEM]INFO
.subtitle Description of the routines--IPCANS
.lm 0.page
The IPCANS routine completes a request to [SYSTEM]INFO or [SYSTEM]IPCC.
It may be used when IPCINF or IPCCON was used with a positive function
code and returned immediately after sending the request.  IPCANS requires
that the first packet in the queue be sent by [SYSTEM]INFO or [SYSTEM]IPCC.
The actions of the routine depend on what the function in the return
message is;  for example,  if the first message is from INFO, and the
function in the message is 3, IPCANS assumes that a name was sent and a
PID is expected in return.  The arguments to IPCANS must be the same
as those of the corresponding IPCINF or IPCCON call, beyond the first 4.
.skip 1
General call:
.break.nofill
	IPCANS(	REF INTEGER ERROR,	;error code returned
		REF INTEGER FUNCT,	;function returned
		REF INTEGER CODE,	;code returned
		REF INTEGER WHO,	;who message is from; see IPCFUN
		    .
		    .
		subsequent arguments);
.fill.para
Actually, you should always call IPCFUN before calling IPCANS.  If you don't,
you will possibly specify arguments of incorrect type to receive the
answer, since you will possibly not know for which function this message
is a response.
.para
This routine would be useless for SAIL, because there is no single way
to declare the type of its arguments that is accurate for responses from
either INFO or IPCC, if it weren't for the following fact:  SAIL will
allow you to declare an EXTERNAL procedure inside a block, which allows you
to do things like:
.skip 1.nofill
	PROCEDURE ANSCODE1;
		BEGIN
		EXTERNAL PROCEDURE IPCANS(...,INTEGER FOO);
		IPCANS(...)
		END;
.skip 1
	PROCEDURE ANSCODE2;
		BEGIN
		EXTERNAL PROCEDURE IPCANS(...,REFERENCE INTEGER FOO);
		IPCANS(...)
		END;
.skip 1.fill
Note that this "trick" would be useful for IPCINF and IPCCON too.
.para
Unfortunately, this "trick" won't work from PASCAL--external procedures
may not be declared inside other procedures.
.subtitle Description of the routines--IPCCON
.page
The IPCCON routine is used to make a request of [SYSTEM]IPCC.
.skip 1
General call:
.break.nofill
	IPCCON(	REF INTEGER ERROR,	;error code
		INTEGER FUNCT,		;function
		INTEGER CODE,		;18 bit code
		INTEGER FLAG,		;non-0 to invoke privileges
		INTEGER JOBPID,		;several uses
		REF INTEGER SND,	;several uses
		REF INTEGER RCV);	;several uses
.fill.skip 1
Although some of these parameters are unused with some functions, BLISS
and SAIL programs must always specify 7 parameters.
.skip 1
Some of the following functions are privileged.  This means that only jobs
that have the IPCF privilege, or are [1,2] may perform them.  Such jobs must
also make parameter FLAG non-0 to tell IPCC that they wish to use their
privileges.
.skip 1
The possible calls are:
.skip 1.lm 16.i -16
1	CALL	IPCCON(ERROR,1,CODE,FLAG,JOBPID)
.break
Enable job's ability to receive packets.  Privileged function if not
your own job.
.i -16
2	CALL	IPCCON(ERROR,2,CODE,FLAG,JOBPID)
.break
Disable job's ability to receive packets.  Privileged function if not
your own job.
.i -16
3	CALL	IPCCON(ERROR,3,CODE,FLAG,JOBPID,INFPID)
.break
Return PID of this job's [SYSTEM]INFO in INFPID.
.i -16
4	CALL	IPCCON(ERROR,4,CODE,FLAG,JOBPID,INFPID)
.break
Create a private [SYSTEM]INFO for the specified job.  INFPID is returned
as the PID of the new INFO.  This is a privileged function.
.i -16
5	CALL	IPCCON(ERROR,5,CODE,FLAG,PID)
.break
Destroy a PID.  This is a privileged function.
.i -16
6	CALL	IPCCON(ERROR,6,CODE,FLAG,JOB,PID,TYPE)
.break
Create a PID for the specified job.  TYPE is non-0 if the PID is to
be dropped on RESET, 0 if the PID is to be dropped on LOGOUT.  This is a privileged
function.  TYPE is passed by reference in BLISS and SAIL.
.i -16
7	CALL	IPCCON(ERROR,7,CODE,FLAG,PIDJOB,SND,RCV)
.break
Set send and receive quotas for the specified job.  This is a privileged
function.  SND and RCV passed by reference in BLISS and SAIL.
.i -16
8	CALL	IPCCON(ERROR,8,CODE,FLAG,PID,NEWJOB)
.break
Change the job number associated with a PID.  This is a privileged function.
NEWJOB is passed by reference in BLISS and SAIL.
.i -16
9	CALL	IPCCON(ERROR,9,CODE,FLAG,PIDJOB,JOB)
.break
Find the job number of a PID.
.i -16
10.	CALL	IPCCON(ERROR,10,CODE,FLAG,JOB,PIDCNT,PIDARR)
.break
Find 1 or more PIDS of a job.
PIDARR is an array that the PIDs are left in.  Note that PIDARR is
supposedly REF INTEGER, so instead of passing the array, you must
pass the first element (eg, instead of
.break
	IPCCON(...,PIDARR);
.break
do:
.break
	IPCCON(...,PIDARR[1]);	)
.break
This is not possible for MACLISP, so you may pass the array name:
.break
	(IPCCON ... 'PIDARR)
.skip 1
On entrance to the routine, PIDCNT contains the size of PIDARR; on exit,
it contains the number of PIDs actually stored.
.i -16
11.	CALL	IPCCON(ERROR,11,CODE,FLAG,JOB,SND,RCV)
.break
Find send and receive quotas for the specified job.
.i -16
12.	CALL	IPCCON(ERROR,12,CODE,FLAG,JOB)
.break
Unblock specified job from RESET.
.i -16
20.	CALL	IPCCON(ERROR,20,CODE,FLAG,INDEX,PID)
.break
Set the specified element of the system PID table.  PID is passed by reference,
except in MACLISP, where it is passed by value.
.i -16
21.	CALL	IPCCON(ERROR,20,CODE,FLAG,INDEX,PID)
.break
Read the specified element of the system PID table.  Value returned in PID.
.lm 0
.subtitle Description of the routines--IPCGET and IPCGTJ
.page
The IPCGET routine returns the contents of GETTAB table 77.
.skip 1
General call:
.break.nofill
	IPCGET(	REF INTEGER COUNT,	;size of array, on input
					;number of items, on output
		REF INTEGER ARRAY [0:9] INFARR);	;holds items
.fill.skip 1
If COUNT is < 0 or > 9,  all entries in the table will be returned.
If 0 <= COUNT <= 9, then only entries 0 - COUNT will be returned.
Upon return from this routine, COUNT will contain the number of items
stored.  This is not true in the MACLISP version:  the value of the function
is the number of items stored.  Therefore, COUNT is passed by value, rather
than by reference.
.skip 1.nofill
N	INFARR(N)
0	MAXIMUM PACKET LENGTH
1	PID of system-wide [SYSTEM]INFO
2	Default quota
3	Total packets sent since reload
4	Total packets outstanding
5	PID of [SYSTEM]IPCC
6	PID mask
7	Length of PID table
8	Number of PIDs now defined
9	Total PIDs defined since reload
.fill.skip 2
The IPCGTJ routine returns the per-job IPCF information that can be found
in GETTAB tables.
.skip 1
General call:
.break.nofill
	IPCGTJ(	REF INTEGER COUNT,	;value in--_# of tables to read
					;value out--_# of tables read
		REF INTEGER ARRAY [0:4] INFARR,	;the GETTAB'ed values
		INTEGER JOB);		;which job to get info about
.fill.skip 1
If COUNT is < 0 or > 4, all items will be returned.  If 0 <= COUNT
<= 4, the specified number of items will be returned.  As in IPCGET, the
number of items gotten will be returned in COUNT, except in MACLISP, where
it will be returned as the value of the routine.  COUNT is passed by value in
MACLISP.
.nofill.skip 1
N	TABLE#	INFARR(N)
0	76	Process communication ID
1	104	IPCF statistics
2	105	IPCF pointers and counts
3	106	PID of job's [SYSTEM]INFO
4	107	IPCF flags and quotas
.fill.subtitle Description of the routines--IPCQER and IPCWQR
.page
The IPCQER and IPCWQR routines query the status of the IPCF receive queue
and return the information they find.
.skip 1
General call:
.break.nofill
	IPCQER(	REF INTEGER ERROR,	;error code
		REF INTEGER FLAGS,	;flags
		REF INTEGER HISPID,	;PID of sender of first message
		REF INTEGER MYPID,	;the PID the message was sent to
		REF INTEGER MESLEN,	;_# of words in first message
		REF INTEGER QUELEN,	;number of packets in queue
		REF INTEGER HISPPN,	;PPN of sender
		REF INTEGER PRIVS);	;capabilities of sender
.fill.skip 1
The bits returned in parameter PRIVS are:
.skip 1
	Bit 0		sender has JACCT bit set
.break
	Bit 1		sender is logged-in
.break
	Bit 2		sender is execute only
.break
	Bit 3		sender has the POKE privilege
.break
	Bit 4		sender has the IPCF privilege
.break
	Bits 18 - 35	job number of the sender
.skip 1
Note:  for compatibility with an earlier version of these routines,
the last two parameters are optional in the FORTRAN or MACLISP version.
If you choose to use them, however, they must both appear.
.skip 1
If there is no packet in the queue, error code 3 will be returned.
The IPCWQR routine is the same, except that if there is no packet in the
queue, it will wait until one arrives, rather than returning code 3.
.subtitle Description of the routines--IPCSML
.page
The IPCSML routine is used to send a small message of 10 words (monitor
dependent) or less.
.skip 1
General call:
.break.nofill
	IPCSML(	REF INTEGER ERROR,	;error code
		INTEGER MYPID,		;pid this message is from
		INTEGER HISPID,		;pid to send to
		INTEGER LENGTH,		;how many words to send
		REF INTEGER ADR);	;address of first word to send
.fill.skip 1
will send LENGTH words from ADR.  ADR must specify an array element.
.break
eg:
.break.nofill
	INTEGER ARRAY FOO[1:100];
	    .
	    .
	    .
	IPCSML(...,100,A[1]);		;send A[1] -- A[100]
	IPCSML(...,105,A[77]);		;send A[77] -- A[182]
.fill.skip 1
Since MACLISP cannot specify an array element by reference, an additional
parameter is provided--the offset into the array.
.break
eg:
.break.nofill
	(ARRAY A FIXNUM 1000)
	(IPCSML ... 100. 'A 0)		;send (A 0) -- (A 99.)
	(IPCSML ... 105. 'A 77.)	;send (A 77.) -- (A 182.)
.fill.subtitle Description of the routines--IPCSND
.page
The IPCSND routine will pack a page with blocks of data and send it to
whomever is specified as the receiver.
.skip 1
General call:
.break.nofill
	IPCSND(	REF INTEGER ERROR,	;error code
		INTEGER MYPID,		;who message is from
		INTEGER HISPID,		;who message is for
		INTEGER FLAG,		;non-0 to allow multiple pages
		REF INTEGER PAGCNT,	;number of pages sent
		INTEGER LENGTH,		;how many words to send
		REF INTEGER ADR);	;where the words are
.fill.skip 1
If FLAG = 0, only one page will be sent.  Ie, if the total length
is greater than 512 (decimal), only the first 512 words will be sent.
If FLAG is non-0, as many pages will be sent as necessary.
.break
PAGCNT is returned with the number of pages sent successfully.
.break
MYPID is optional.  If = 0, the PID most recently assigned with
IPCINF will be used.
.skip 1
FORTRAN programs may specify any number of blocks of data to
be packed on the page.
.break
	CALL IPCSND(...,5,DATA(16),20,DATA(72),7,DATA(50))
.break
will cause DATA(16) - DATA(20), DATA(72) - DATA(91), and DATA(50) - DATA(56)
to be packed into the message.
.skip 1
A similar capability exists in MACLISP.  As in IPCSML, however, an offset
must be specified for each array.  Eg:
.break.nofill
	(ARRAY DATA FIXNUM 1000)
	(IPCSND ... 5 'DATA 16. 20. 'DATA 72. 7 'DATA 50.)
.fill.break
will cause (DATA 16.) - (DATA 20.), (DATA 72.) - (DATA 91.), and (DATA 50.) - (DATA 56.)
to be packed into the message.
.subtitle Description of the routines--IPCRCV
.page
The IPCRCV routine is used to receive a message and unpack it into blocks
wherever the user specifies.
.skip 1
General call:
.break.nofill
	IPCRCV(	REF INTEGER ERROR,	;error code
		REF INTEGER MYPID,	;pid message sent to
		REF INTEGER HISPID,	;pid of message sender
		INTEGER FLAG,		;non-0 to retain message
		INTEGER OFFSET,		;first word of message to look
					;at (0 -- 511.)
		INTEGER LENGTH,		;how many words to get
		REF INTEGER ADR);	;and where to put them
.skip 1.fill
MYPID and HISPID are returned.  OFFSET is the word in the message to start at.
FLAG should be non-0 to retain the message, so that the next call to IPCRCV will
read from the same message.
.skip 1
As in IPCSND, FORTRAN programs may specify multiple blocks to receive into:
.break.nofill
	CALL IPCRCV(...,5,DATA(4),10,DATA(60),...)
.FILL.skip 1
Likewise, MACLISP programs may specify multiple blocks, and MUST specify an
offset:
.break
	(IPCRCV ... 5 'DATA 4 10. 'DATA 60. ...)
.fill.subtitle Description of the routines--IPCDIS and IPCERR and IPCINI
.page
The IPCDIS routine discards the first message in your receive queue.
.skip 1
General call:
.skip 1
	IPCDIS(REF INTEGER ERROR);	;error code
.skip 3
The IPCERR routine types a message identifying IPCF error code.
.skip 1
General call:
.skip 1
	IPCERR(INTEGER ERROR);		;types message for given code
.skip 3
Routine IPCINI is needed in versions of the IPCF package that do their own _.JBFF
core management, rather than using that provided by a runtime system.
SAIL and FORTRAN's runtime systems provide suitable core management.  The
MACLISP version uses nameless FIXNUM arrays for temporary storage.  Therefore,
IPCINI is present only in the PASCAL and BLISS versions.  The _.JBFF core management
provided for these languages is compatible with CSL PASCAL and BLISS programs with
simple _.JBFF core management.  Use with more complex core management will
require modifying the GETCOR and RETCOR routines in IPCF.MAC to call the user's
core allocation/deallocation routines. If this is done, IPCINI will
probably be unnecessary.
.skip 1
General call:
.break
	IPCINI;		(*PASCAL*)
.break
or:
.break
	IPCINI();	%BLISS%
.subtitle Error codes
.page
The following table describes the meaning of the error codes returned in
the ERROR parameter (as the value of the functions, in MACLISP).
.skip 1.lm 16
.i -16
^&Error code\&######^&Meaning:\&
.skip 1
.i -16
##0 or NIL######No error. (IPCF.FAS returns NIL to indicate no-error).
.skip 1
.i -16
;IPCF system error codes:
.break.i -16
*#1#############Address check.
.break.i -16
*#2#############Block not long enough to receive message.
.break.i -16
##3#############No packet in receive queue.
.break.i -16
*#4#############Page in use.
.break.i -16
*#5#############Data too long for buffer.
.break.i -16
##6#############Destination unknown (receiver's PID unknown).
.break.i -16
##7#############Destination disabled.
.break.i -16
##8#############Sender's quota exceeded.
.break.i -16
##9#############Receiver's quota exceeded.
.break.i -16
#10#############No room in system storage to store small message.
.break.i -16
*11#############Sender specified invalid page number, or receiver specified
an existent page.
.break.i -16
#12#############Sender's PID invalid.
.break.i -16
#13#############Insufficient privileges to perform function.
.break.i -16
*14#############Unknown function specified.
.break.i -16
#15#############Bad job number specified.
.break.i -16
#16#############PID table is full.
.break.i -16
*17#############Page mode packet when non-page mode expected, or vice versa.
.break.i -16
#18#############Paging I/O error.
.break.i -16
#19#############A bad index has been specified for the system PID table.
.break.i -16
#20#############Undefined ID in system PID table.
.skip 1
.i -16
;[SYSTEM]INFO errors
.break.i -16
#56#############[SYSTEM]INFO has an unknown, internal error.
.break.i -16
#57#############[SYSTEM]IPCC request from [SYSTEM]INFO failed.
.break.i -16
#58#############[SYSTEM]INFO failed to complete a request to assign a PID or
a name.
.break.i -16
#59#############Your job's PID quota has been exceeded.
.break.i -16
#60#############An unknown PID has been specified.
.break.i -16
#61#############A duplicate name has been specified.
.break.i -16
#62#############An unknown name has been specified.
.break.i -16
#63#############The name specified has illegal characters.
.skip 1.i -16
;routine error codes
.break.i -16
#-6#############No room to store message.
.break.i -16
#-5#############Message not from INFO or IPCC.
.break.i -16
#-4#############Message not from INFO.
.break.i -16
#-3#############Unknown function.
.break.i -16
#-2#############"Impossible" UUO failure.
.break.i -16
#-1#############Unknown receiver.
.lm 1.skip 2
* These errors are not expected to occur.  They represent an internal error
in the routines.  Please report any occurance of these to a system programmer.
.subtitle Description of the routines
.lm 0