Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
kcc-5/lib/usys/codsys.doc
There are 5 other files named codsys.doc in the archive. Click here to see a list.
CODSYS.DOC - Information on writing USYS routines.
Writing USYS routines:
USYS Header Files
<sys/usysio.h> T20 Defs for USYS I/O routines.
<sys/usysig.h> T20 Defs for USYS Signal stuff.
<sys/usytty.h> T20 Defs for USYS TTY stuff.
In order to implement signal handling correctly, we have to ensure
that no USYS routine has control wrested away from it, leaving internal
data in an inconsistent state. For this reason certain rules
must be followed:
[1] At the START of a USYS routine, invoke the macro USYS_BEG().
This and other USYS_ macros are defined in <sys/usysig.h>.
[2] When RETURNING from a USYS routine, invoke one of the following macros:
USYS_RET(val); Return a local variable or constant value.
USYS_RETVOLATILE(val); Return a volatile (global or function) value.
USYS_RETERR(err); Return -1, setting errno to "err".
USYS_RETINT(); Return -1, setting errno to EINTR.
Each of the USYS_RETxxx macros serves as a "return" statement, and
each takes care to process any pending signals. If a signal occurred
during the USYS routine, it is deferred until the USYS_RETxxx happens,
and is then handled just before returning to the user's program. The
reason for distinguishing RETVOLATILE from simple RET is because the
former case must save the return value in a temporary local-scope
location while any pending interrupts are processed. Otherwise, by the
time the actual return took place, the return value may have changed from
what it should have been!
Non-interference:
USYS routines are assumed not to interfere in any way with
non-USYS library functions. Thus, it is very, VERY bad for a USYS
routine to call a C library function which changes static data; the
user program will not be expecting this. Note that signal handlers
must be able to execute system calls, and any normal C library
function could be interrupted. malloc(), in particular, cannot be
used by a USYS routine for this reason!
JSYS calls:
When making a JSYS call, "fast" and "slow" calls need to be
distinguished. "fast" calls are those which never block or hang, and
for which no asynchronous PSI interrupts are expected to happen;
"slow" calls are those which have the potential to hang for indefinite
amounts of time, and should be considered interruptible. If using a
"slow" call, the JSYS_INTERRUPTABLE flag should be added to the
JSYS-number argument in the call to jsys(). The latter will return -1
if the call was interrupted, and in this case the USYS routine should
return with USYS_RETINT().
Things are actually a little more complicated than this, as
certain calls such as read() and write() must check to see whether they
should really be interrupted or if the signal handler permits them to
continue what they were doing. This is done by invoking USYS_END() and
examining its return value to see what happened. Look at the existing
code for read(), write(), and ioctl() for examples.