mirror of
https://github.com/PDP-10/its.git
synced 2026-01-13 15:27:28 +00:00
Binary-only compiler and library, plus documentation and include files for compiling new programs.
60 lines
2.8 KiB
Plaintext
Executable File
60 lines
2.8 KiB
Plaintext
Executable File
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.
|