[Info-vax] QIO Writes to a mailbox
George Cornelius
cornelius at eisner.decus.org
Sat Nov 5 04:53:15 EDT 2011
VAXman- @SendSpamHere.ORG wrote:
> I'd lose the event flag and use EFN$C_ENF and use a $QIOW wherein I'd
> CHECK the status in the IOSB _OR_ I'd check the IOSB in the AST routine
> ***ASSUMING*** you allocate a separate one for each $QIO... Oh, and do
> not allocate it in the C routine variables... These some off the stack
> and will be invalid when the routine returns to caller. Allocate them
> with a malloc() or one of the VMS memory allocation routines like the
> LIB$GET_VM (which is jacketted by malloc() anyway).
I would expect a global definition would work. It would need a _volatile_
qualifier as well. Oh, but I suppose you are trying to deal with multiple
outstanding I/O's. The old assembler programmer trick is an array of
entities - structures - each containing an IOSB and any context that might
be needed, say a buffer pointer, to properly process the completion.
Don't forget the volatile declaration on things that will change
asynchronously to program execution. malloc() is fine, but if the amount
of static space required to handle the most complex possible scenario
is too high then you may have a design you haven't thought all the way
through anyway.
Aren't there ways to link in C that guarantee you are using AST reentrant
libraries? That might be of interest as well, especially if you call
C library routines at AST level.
It was claimed earlier in the thread that a nowait modifier
on the I/O function code was the same as using $QIOW. There is a
significant difference, as I recall. A $QIOW blocks (waits) until
the operation you requested has completed. An IO$M_NOW modifier
changes _what_ is requested. In fact, I believe the modifier asks
that the data be copied to nonpaged pool and then a success status
be returned in the IOSB, while the default is for the I/O to not
complete until the data has been successfully transferred to a
receiving program's buffer.
There is a discipline to using asynchronous I/O operations in VMS,
and the first aspect of it is understanding the various mechanisms
involved and realizing that some, such as those involving mailboxes,
require additional care on your part. The second is using the
appropriate constructs within your programming environment to
achieve your goals, and it is very important to understand that
(a) optimizing compilers can be easily fooled by things that change
while they aren't looking, and (b) automatic allocation, say on the
stack, for the duration of a subroutine issuing an I/O, is almost
always incorrect unless the subroutine guarantees that the variables
will no longer be referenced - the asynchronous events are no longer
pending - once the subroutine exits.
The is a corresponding discipline to writing AST code - and
multithreaded code in general - and one of the key requirements
other than appropriate use of the volatile declaration involves
error handling, and signalling between AST level and main level
code in general.
It is very easy to have race conditions, especially if you look
at individual lines of code and think that they are in some
sense atomic. If you don't just issue $EXIT_S from the AST
level when you decide to abort, then set an abort flag so
subsequent AST's will not continue to propagate execution,
and signal (and awaken!) the main level to have it exit as
directly as possible, thus avoiding a lot of otherwise sticky
wick^H^H^H^H issues. Remembering, of course, that awaking
a process in a $QIOW typically involves cancelling the pending
operation.
George
More information about the Info-vax
mailing list