diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/etc/doc/psio.doc | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'sys/etc/doc/psio.doc')
-rw-r--r-- | sys/etc/doc/psio.doc | 275 |
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. |