aboutsummaryrefslogtreecommitdiff
path: root/sys/etc/doc/psio.doc
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/etc/doc/psio.doc
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'sys/etc/doc/psio.doc')
-rw-r--r--sys/etc/doc/psio.doc275
1 files changed, 275 insertions, 0 deletions
diff --git a/sys/etc/doc/psio.doc b/sys/etc/doc/psio.doc
new file mode 100644
index 00000000..d0f34c9a
--- /dev/null
+++ b/sys/etc/doc/psio.doc
@@ -0,0 +1,275 @@
+.help pr_psio
+.nf __________________________________________________________________________
+PR_PSIO -- Pseudofile i/o for a process. Process an i/o request for the
+specified pseudofile stream of the specified process. Called either to read
+command input from the CLIN of a process, or to process a read or write
+request to a pseudofile of a process.
+
+
+1. Introduction
+
+ Pseudofile i/o in a multiprocess configuration, e.g., for the graphics
+streams, is quite complex and difficult to explain briefly. I have tried to
+cover the major points here but warn the reader that it is not going to be easy
+to understand the flow of data and control involved. The problem is a difficult
+one due to the nature of the IPC protocol and the complexity of the three
+process architecture required when an external graphics kernel is used. The
+discussion herein is not complete but should as least give the reader some
+idea of what is going on.
+
+
+2. Pseudofile I/O
+
+ While a task is running the CL will be reading command input from the task.
+This read eventually resolves into a call to PR_PSIO on the CLIN for the
+process. When pseudofile i/o occurs, e.g., the process writes to STDOUT or
+STDERR, an XMIT or XFER directive will be seen in the CLIN input from the
+process. If we are directed to XMIT to an ordinary file our task is relatively
+easy, i.e., we read the data block from CLIN and write it to the output file.
+A directive to read from the standard input is also easy, i.e., we read from
+the standard input of the parent (assuming i/o is not redirected) and write
+the data block to the CLOUT of the process preceded by a count of the number
+of chars.
+
+
+2.1 I/O to a Graphics Stream
+
+ If we are directed to read or write a graphics stream our task is somewhat
+more difficult. The standard graphics streams STDGRAPH, STDIMAGE, and STDPLOT
+differ from other pseudofiles in that the streams are both readable and
+writable, provided all data is used up before switching modes. A graphics
+stream may be connected to a file if output is being spooled, to the builtin
+STDGRAPH kernel if the graphics device is the graphics terminal, or to a
+graphics kernel resident in an external subprocess.
+
+If a graphics stream is redirected to a spool file we merely copy output to
+the file and reading is forbidden. If output is to an external graphics
+kernel but is unfiltered (no workstation transformation, e.g., for STDPLOT),
+we merely copy data blocks on to the subprocess but the protocol involved
+is nontrivial. If output is to the builtin STDGRAPH kernel or to an
+external interactive kernel, output must be filtered through GIOTR before
+being written to the local or remote graphics kernel. Graphics input is
+also possible and is handled similarly but without need to call GIOTR.
+
+Before reading or writing a graphics stream GIO will send a special directive to
+PR_PSIO to connect a kernel to the stream. This directive is passed to PR_PSIO
+via an XMIT to the special pseudofile PSIOCONTROL. The data passed in the
+XMIT call will be the GKI control instruction to be executed by PSIO. There
+are currently three such directives, i.e., OPENWS, SETWCS, and GETWCS. Each
+such directive is included in the normal metacode stream as well, but by
+writing to a special pseudofile we avoid the need to have PR_PSIO scan each
+metacode stream for control instructions, a fairly expensive operation if a
+lot of data is involved.
+
+
+2.1.1 Graphics Stream Dataflow
+
+ A frame buffer is associated with each graphics stream in the parent
+process. If graphics output (metacode) is being filtered, each output record
+is appended to the frame buffer and then GIOTR is called to filter the new
+instructions. GIOTR writes the filtered metacode stream either directly to
+the builtin kernel or to the graphics output pseudofile stream of the parent
+process.
+
+Output to the builtin kernel is easy to understand: GIOTR merely calls the
+kernel to execute the transformed instruction. If output is to an external
+kernel we unfortunately cannot simply write to the kernel because we require
+that the graphics kernel task be a conventional task callable from either
+the CL or by the graphics system, i.e., by PL_PSIO. We must buffer the
+transformed output metacode and pass it on to the kernel process only when
+requested to do so by an XFER command from the kernel.
+
+This buffering is done in a somewhat tricky way which makes it look like we
+are writing to a simple file, and which allows us to use conventional READ and
+WRITE calls to access the graphics stream. GIOTR, if not writing to the
+builtin kernel, will write to one of the three graphics streams of the parent
+process, i.e., to STDGRAPH, STDIMAGE, or STDPLOT. The graphics stream of the
+parent is logically connected to the same stream in the kernel process. We
+arrange things such that data may be written or read into the FIO buffer
+associated with the stream, but the buffer will never actually be flushed,
+since this would cause the contents to appear as garbage on the user terminal.
+
+The sequence of events for an XMIT to STDGRAPH with an external kernel is as
+follows:
+
+
+ The parent process (CL) blocks, waiting for a read on the IPC
+ channel to the graphics task.
+
+ Graphics task writes to stdgraph.
+ FIO flushes stdgraph buffer through IPC channel.
+
+ PR_PSIO (in the parent) sees XMIT to stdgraph.
+ Parent reads data record from IPC channel, appending the
+ data record to the frame buffer for the stream.
+
+ PR_PSIO calls GIOTR to process the new metacode.
+ GIOTR writes the transformed metacode instructions to the stdgraph
+ stream of the parent and returns control to PR_PSIO.
+
+ PR_PSIO rewinds the stdgraph buffer in preparation for a read and
+ stacks the pending XMIT request and directs its command input
+ to the IPC of the kernel process.
+
+ The kernel process sends zero or more XMIT or XFER requests to
+ the parent to read or write pseudofile streams other than
+ stdgraph.
+ The kernel process sends an XFER request to the parent to read
+ from stdgraph.
+ The parent reads the data record from the stdgraph FIO buffer
+ and passes it on to the kernel, completing the XFER request
+ of the kernel as well as the original XMIT request of the
+ graphics task.
+
+ The parent process (CL) blocks, waiting for a read on the IPC
+ channel to the graphics task.
+
+
+The sequence of operations for an XFER request from the graphics task is
+as follows.
+
+ The parent process (CL) blocks, waiting for a read on the IPC
+ channel to the graphics task.
+
+ The parent receives an XFER request from the graphics task.
+ If there is any data in the stdgraph buffer the parent returns
+ that to the graphics task, otherwise the PR_PSIO procedure
+ pushes an XFER request and redirects its input to the
+ graphics kernel.
+
+ The kernel process sends zero or more XMIT or XFER requests to
+ the parent to read or write pseudofile streams other than
+ stdgraph.
+ The kernel process sends an XMIT request to the parent to write
+ to stdgraph.
+ The parent reads the data block from the IPC channel to the kernel
+ and writes it to stdgraph, completing the XMIT request.
+
+ The parent pops the XFER request and copies the data in the stdgraph
+ buffer to the graphics task, completing the original XFER request.
+
+ The parent process (CL) blocks, waiting for a read on the IPC
+ channel to the graphics task.
+
+
+In summary, the principal data buffers involved in pseudofile i/o to a graphics
+stream are the frame buffer, used by GIOTR to spool the metacode instructions
+for a graphics frame, and the FIO buffer for the graphics stream, used to
+pass data between XMIT/XFER request pairs from cooperating processes at
+opposite ends of a graphics stream.
+
+
+3. Summary
+
+ The actual code required to implement all this is probably easier to
+understand than the English description. To summarize the justification for
+the complexity of the scheme we have adopted:
+
+ [1] The graphics kernel task is a conventional CL callable task with
+ parameters etc., usable to process metacode from a metafile or from
+ a pipe as well as callable by PR_PSIO. The conventional IPC protocol
+ is used in the graphics kernel task. Other tasks may be resident in
+ the same process, saving disk and memory.
+
+ [2] The graphics kernel may read STDIN and write STDOUT and STDERR while
+ processing metacode, allowing access to the graphics terminal via the
+ CL process, output of debugging information during operation, and
+ output of error messages during operation.
+.endhelp ______________________________________________________________________
+
+
+# PR_PSIO -- Process an i/o request for the specified pseudofile stream
+# of the specified process.
+
+procedure pr_psio (pid, active_fd)
+
+pid process id
+fd process stream for which i/o is requested
+
+begin
+ in = pr.clin
+ fd = active_fd
+ clear stack
+
+ # Process i/o requests from the subprocess until a request is received
+ # and processed for pseudofile FD.
+
+ repeat {
+ while (filbuf (in) != EOF) {
+ determine type of request and destfd
+
+ if (xmit request to stream destfd) {
+ if (graphics filtering enabled) {
+ read data record and append to frame buffer
+ call giotr to filter output to destfd
+ } else {
+ read data record from process
+ write record to destfd
+ }
+ if (destination is a process) {
+ rewind destfd buffer for read
+ push (fd)
+ push (in)
+ push (xmit)
+ fd = destfd
+ in = newpr.clin
+ next
+ }
+
+ } else if (xfer request from stream destfd) {
+ if (destfd is a process and buffer is empty) {
+ push (fd)
+ push (in)
+ push (xfer)
+ fd = destfd
+ in = newpr.clin
+ next
+ } else {
+ read data record from destfd
+ write data record to process
+ }
+
+ } else if (gio directive) {
+ if (open workstation)
+ connect a kernel process to a graphics stream
+ else if (setwcs)
+ save wcs for the stream
+ else if (getwcs)
+ write wcs data to the process
+
+ } else {
+ destfd = CLIN
+ if (fd != CLIN)
+ error: unsolicited command input from the subprocess
+ }
+
+ if (destfd == fd) {
+ if (stack not empty) {
+ pop (request)
+ pop (in)
+ pop (fd)
+ if (request == xfer) {
+ read data record from fd
+ write data record to process owning "in"
+ }
+ } else
+ break
+ }
+ }
+ } until (stack is empty)
+end
+
+
+
+File routing:
+
+ Each pseudofile in a subprocess is associated with a stream in the parent
+process. A subprocess pseudofile may map to a real file or to a parent
+pseudofile. When a subprocess is connected as a graphics kernel graphics
+i/o will be via any one of the standard graphics streams STDGRAPH etc.,
+with said graphics stream connected to the same stream in the parent.
+The subprocess streams STDIN, STDOUT, and STDERR are by default connected
+to the same streams in the parent, allowing the subprocess to access the
+terminal, output error messages, and so on. A graphics kernel will be able
+to access the standard i/o streams even while connected as a subprocess
+to filter GKI metacode.