Post by Chris ScheersI think this message shows the source of the confusion.
The AST dispatch/return mechanism has nothing to do with Macro32 or any
other language.
VMS and the VAX hardware were designed together. The implementation of
each affected the other and various decisions and trade offs were made
to produce a viable solution given the hardware limitations of the time.
A large part of what made VMS's capabilities unique in the day was the
AST. This provided capabilities that other OSes (including Linux and
Windows) have yet to provide. Likewise, it also required restrictions
that other OSes (including Linux and Windows) do not have.
In VAX/VMS, there is not a software AST "routine" dispatcher.
The AST dispatch/routine mechanism is implemented in the VAX hardware.
The extra "arguments" are the hardware context required by the VAX
hardware to correctly execute the AST return.
The programing practice has always been to ignore those arguments.
Would a pure software design have done it some other way. Of course!
But such a software redesign would have impacted more than just VMS.
ASTs are used in many user mode programs.
If you want to blame something, blame the VAX hardware design. But,
that very design is what made VMS viable in the 1970/1980s time frame.
The VAX/VMS AST delivery code is not hardware. It's software. The code
is located in module ASTDEL (see routines SCH$QAST, SC$ASTDEL,
EXE$ASTRET, etc), and the code had the choice of saving arguments onto
the argument list or saving arguments on the other side of the frame
pointer for the AST, and the developer chose oddly.
A REI instruction triggers an interrupt to go check for some pending
work, and that interrupt then runs a whole lot of software. Including
the CALLG used to pass control to the AST code. Since it was a CALLG
instruction used to pass control to the AST, passing one argument would
have worked as well as five. Not that use of a CALLS would have
significantly changed the flow, other than moving the AP/FP around a
little and wasting some stack. But we have five arguments.
AST delivery does need to preserve the registers involved (as CALLS and
CALLG do not preserve R0 and R1 per the calling standard), though the
visibility of those added arguments on the AST call are basically
useful only for causing corruptions in apps. Which is what Simon is
grumbling about. The whole design tends to point to latent
argument-mismatches in many uses of ASTs, too. That'll be fun to fix,
just as soon as better diagnostics are enabled in the various
programming languages the ASTs are written using.
And that AST argument list design is not changing soon. There's no
reason to change this current ASTDEL argument-list design ~forty years
on either, absent larger changes such as those involved with some
hypothetical implementation of object-oriented message-passing support
on OpenVMS.
Post by Chris ScheersPost by Simon ClubleyPost by abrsvcI find these kind of comments somewhat offensive since it is easy to
criticize the decisions of people made 40 years ago using the context
of knowledge today. VMS was designed as a cooperative pairing of both
hardware and software. The use of R0 and R1 was for consistency across
calls and had nothing to do with MACRO32 at all. Bliss used the same
register conventions. If the VMS and VAX engineers knew in the late
70's what was known now, I suspect things would have been done
differently.
Hello Dan,
The problem is not the preserving of R0/R1/PC/PS{L}, but the way in
which it was done. This information should be private to the AST
dispatcher that calls the AST routine. It should never be visible to
the called AST routine itself because that is an outright violation of
good modular design and that's as true back when VMS was designed as it
is now.
In case you are familiar with bare metal interrupt programming, you can
compare the calling of an AST routine with the way that an interrupt
handler is called when working with bare metal code or when
implementing an OS itself.
On more advanced MCUs, you can have an assembly language interrupt
dispatcher that calls the actual C language interrupt handler and you
can end up having to save more interrupt state than just the normal
registers in your assembly language interrupt dispatcher.
However, that information is always private to the interrupt
dispatcher, and is _never_ exposed to the interrupt handler itself and
this is so universally true, that I didn't even realise what the AST
registers were being used for until it was pointed out to me.
For example, in one bare metal assembly language interrupt dispatcher I
wrote a while back for an ARM processor and which I was looking at
recently, the dispatcher has to save what is called the priority
limiter register before programming a new value (this allows nested
interrupts to occur).
This is saved onto the stack by the dispatcher before calling the C
language interrupt handler and is restored by the interrupt dispatcher
upon return from the interrupt handler. This information is private to
the dispatcher, it is not visible to the interrupt handler, and I would
never design a system where it was, because that is an utter violation
of modular and good programming practice.
That priority limiter register can be compared to one of those private
AST registers and that's why I consider it so wrong that those private
registers are there in the AST call frame and hence visible to the
called routine as it's an utter violation of good modular design.
As for some of the other replies in this thread...
Threading is now baked into OpenVMS (KP), into Linux (POSIX AIO since
2.6, io_uring/liburing more recently, etc), and similarly built into
most other platforms. ASTs aren't particularly unique in 2021.
Ignoring the hardware register stuff in the VAX/VMS AST argument list,
ASTs are somewhat a pain in the arse as compared with some other
designs too, but ASTs can and do work. And KP threading isn't all that
well integrated into the OpenVMS system service calls. There are some
discussions on mixing threads and ASTs around on OpenVMS, and there are
subtleties awaiting app developers here. The OpenVMS documentation did
not cover this area at all well, when last I checked.
As for whether Macro32 was involved in this design? Donno. Kernels
still tend to mess with registers in some corners, and assemblers are
still better than that than is C with asm or built-ins, or some other
alternative. Though we're getting pretty close with the alternatives.
There are other stupid ideas in OpenVMS, such as the successful access
violation, and using localtime in the system clock.
Oh, and there was a replacement created for VAX/VMS at DEC—built with
things learned from VMS and other work—and that replacement has been
quite successful in the market. That replacement? DEC MICA. For some
posters, a platform which largely sees references around here in the
comp.os.vms newsgroup as a source of examples of mistakes that OpenVMS
should... emulate? implement? something.
--
Pure Personal Opinion | HoffmanLabs LLC