Why use U* over VMS
Kevin Quick, Simpact Assoc., Inc.
kquick at dcs.simpact.com
Tue Oct 30 08:40:05 AEST 1990
In article <1990Oct25.160937.28144 at edm.uucp>, geoff at edm.uucp (Geoff Coleman) writes:
> From article <ANDYO.90Oct23101417 at glasperl.masscomp>, by andyo at glasperl.masscomp (Andy Oram):
>> This group is comp.unix.programmer, after all. Isn't there someone out there
>> who can summarize the differences in working with the guts of VMX and UNIX,
>> someone who can speak from the experience of porting highly interactive
>> applications or writing device drivers or something like that? There must be
>> some good general learning experiences here.
>>
> Sorry I missed the original question so I might be jumping in with both
> feet firmly implanted in mouth here.
>
Likewise, I missed the original question: if the comments below are irrelevant
or irritating, please place all responses in a file and copy it to /dev/null
or NLA0:, whichever you prefer...
Now, ignoring all OS wars and "mine's better than your's" claims, I humbly
offer my experience as someone who's worked in both U*x and VMS. The following
is very long, so you may want to save it for later.
Applications:
-------------
1. Applications written in Unix that use fork, exec, or system will need
to be changed and will suffer significant performance degradation under
a corresponding VMS implementation. Also, the standard utilities usually
invoked by system or exec are not present under VMS, so you may end up
having to write your own replacements if there are no similar VMS
utilities available. Usually, the VMS libraries provide routines to
accomplish what the Unix programmer calls shell routines for, so
it requires some modest code changes. This makes VMS programs much
more self-contained at the possible expense of re-inventing algorithms
(unless you're smart).
2. Files can be tricky for someone familiar with one OS looking at another
OS, in either direction. This isn't really a major concern unless you
need to communicate files from one OS to the other via FTP or similar
transfer program. If so, then you may need to modify the VMS FDL
description of the file to "Stream-LF" to get VMS to interpret your
file the same way as Unix does. Also beware that binary mode transfers
to VMS are likely to pad your file out with nulls until its size is
an integral of 512 bytes. To get an FDL description of a file, use
"CREATE/FDL filename"; the output filename.FDL file may be edited as
described above, and then the file may be updated by the CONVERT/FDL
routine as necessary. Since there are lots of parameters here, I
won't go too deep, as some experimentation may be necessary.
The RMS library (Record Management Services) under VMS provide a
program level interface to many different types of files, allowing
specific directives and general read/write requests for a file that
force the RMS to do all the work like sorting, searching, etc. This
generally makes writing database applications easier under VMS since
you don't have to parse the file yourself, at the expense of a simple
representation that may be interpreted in many ways. A few simple
parameters in the VAX C extension of the fopen call allow optimization
of file accesses to a particular method, allowing the programmer who
knows how the file will be used to increase the speed of his program.
3. Another sometimes surprising element of VMS is that a single file can
(and usually does) have multiple versions existing at any one time. This
means that opening an existing file for create/write access will cause
a new file with an incremented version number to be generated rather than
replacing the currently existing file. Therefore, Unix utilities which
use temporary files or similar concepts may need to be enhanced to clean
up properly after themselves, whereas VMS programmers are likely to be
very uncomfortable for a while with no backup of their work.
4. Overall, the C RTL is very similar between Unix and VMS, with the effort
for VMS C being to adhere to the C "standard" (chuckle, chuckle :-) and
make non-destructive language enhancements where needed. There are some
changes, but those are usually documented, and are found by the linker
under worst case.
As far as the system RTL availability, the VMS has a large and very
convenient RTL, which is implemented with a general callable interface
that allows ANY supported language under VMS to access the RTL in a
generic fashion. Unfortunately, this callable interface uses a "string
descriptor" for string representation, which does not coincide with
the zero-terminated string representation in C, so some extra effort
needs to be made here, but once you do it a time or two, it becomes
rote (and macro-able).
5. VMS supports a very large number of third-party terminal devices, so
it is not probable that you are going to have problems here. Although
VMS C implements curses, I find the native VMS SMG screen management
utilities much more pleasing.
6. VMS has a large run-time library available, completely separate from C,
which is available to perform a large variety of tasks, including lock
management as mentioned by another poster here. This means that you
can continue to write your programs with maximum portability in mind,
in which case you make very few assumptions about your environment and
do almost everything yourself, or you can write a VMS specific utility
which is optimized both in speed and size for the VMS environment. Also,
since portability is not a large requirement for VMS itself, some of
the capabilities (such as screen management mentioned earlier) can take
significant advantage of known environmental characteristics.
Drivers:
--------
Because the OS's are considerably different, driver writing is as well. A
driver is, by definition, a three-way bridge between the operating system,
a device, and the application program. If you are writing a device driver,
there are several significant differences to be aware of. My general
impression is that the Unix environment for a driver is much simpler and
therefore easier to write to, whereas the VMS environment is more
complicated, but provides better tools.
1. VMS has the concept of allocatable virtual memory, which may be obtained
by calling system routines; most VMS device drivers use this technique
for buffering data, etc.
Unix (usually) also has the concept of allocatable virtual memory (implying
non-pageable, kernel space), but few Unix drivers actually use this
technique. The Unix drivers (that I've seen) usually pre-allocate a large
chunk of memory at compile time and use that memory as needed.
The problem arises in that, while VMS returns an error indicating when
no memory is available, Unix simply "sleeps". This is effectively a
suspending of the current process until memory becomes available.
Unfortunately, the VMS driver does not depend on process context to
execute, which brings us to point 2:
2. In Unix, when an application issues a driver request, the PC is transferred
to the appropriate driver routine in kernel and remains there, in execution,
until the request completes, at which time the routine exits and the user
level code resumes. There is no Unix implementation of "no-wait",
"asynchronous", or "background" IO.
In VMS, the application issues a driver request. That process is then
placed in a wait state after a VMS structure is initialized to describe
the request. That structure is then passed through several parts of the
device driver in several stages and interrupt levels to accomplish the
request. Each intermediary routine is free to do its work and then exit
which returns to the OS. When the user's request is finally completed,
a specific "wakeup" is issued to the process with an output status.
At this point, VMS introduces the "no-wait" IO, where the process is not
actually placed in a wait state when its request is issued. The descriptive
structure is created and begins its trek through the driver, but the process
continues execution. The process can actively poll for completion of the
request, or an asynchronous routine may be specified to be activated by
the OS when the IO completion "wakeup" is issued. This allows true
"no-wait" IO, along with multiple outstanding requests.
3. Everything except interrupt handlers in Unix are written in "user"
context, whereas only the preliminary portion of a VMS driver (the
FDT routines) are in user context.
This means that all buffer validation and copying from the user space
must be done from the FDT routines in VMS; copyout of data after the
request completes is done by VMS based on addresses and flags in the
structure describing the request.
This also means that, whereas a Unix driver has a relatively straight-
forward code flow, with perhaps a sleep to await later rescheduling,
the VMS environment is more versatile at the cost of a much more
complex code flow.
Care must be taken in a VMS driver not to access user level data and
such from most of the driver, whereas a Unix driver must insure user
context for kernel memory allocation, sleep requests, and much more.
4. The VMS synchronization is much more specific and explicit, and in
some cases much better than Unix synchronization, but that is partially
because VMS is specific to Digital machines, whereas Unix is forced
to be much more general.
5. With a few considerations, it is possible to re-load a driver into a
running VMS system, and it is also possible to boot a VMS system without
a driver. This generally means that the debugging turnaround is faster
in a VMS environment:
VMS: Boot system Unix: Boot system
Compile & link driver Compile & link driver
Install driver into system Build new system with driver
Run test programs Reboot to run system w/driver
Hit bug Run test programs
Reboot system Hit bug
Analyze dump Reboot system
Fix, compile and link driver Analyze dump
Install driver into system Fix, compile, and link driver
Run test programs Build new system w/fixed driver
: Reboot with new system
Run test programs
:
where the Unix steps of building a system and rebooting take a significant
amount of time as compared to the milliseconds it takes to install/load
a VMS driver.
Overall, VMS provides a much more versatile environment at the cost of a
much more specific and complex driver environment. I've typically taken
the approach of using a daemon process in Unix to provide a general process
context for a "dispatcher" to emulate the VMS "fork dispatcher" functionality
for asynchronous, multiple-event drivers. This is probably a result of my
VMS background, and might have been done differently had I started out as
a Unix programmer, but means that for most of the driver work I do, I find
the VMS environment more convenient and spend some time reproducing elements
of that environment in the Unix world.
Both environments can be rewarding and fulfilling, but it takes an open
mind and a willingness to examine ones algorithms and restructure them
as necessary. My impression is that I would much rather be a VMS driver
writer learning the looser Unix environment than the Unix driver
writer that must climb a large learning curve to get into the VMS environment.
If you can do both, then your only problem is switching mental gears about
40 times a day to answer various questions! ;-)
If you have specific questions or comments, email me (address below), but
no guarantee on turnaround time.
--
-- Kevin Quick, Simpact Associates, Inc., San Diego, CA.
Internet: simpact!kquick at crash.cts.com
More information about the Comp.unix.programmer
mailing list