[Info-vax] New free Load Average driver (LAXDRIVER) to replace LAVDRIVER
Jake Hamby
jake.hamby at gmail.com
Fri Jun 17 18:39:32 EDT 2022
I'm not quite ready to announce a V1.0 release, but I'm pleased to share my first VMS device driver, not for a physical hardware device, but a replacement for the old LAVDRIVER load average driver written in MACRO. With the recent thread bemoaning the lack of good examples of how to write a device driver in C, I'm happy to add to the collection of open source examples.
I'm in the process of upgrading the GNV packages with various bug fixes, although my branch is definitely not as stable as the release packages. However, there's a bug in coreutils in "uptime", "w", and other programs that show the load average.
The getloadavg.c code in the original coreutils source actually has VMS support (and Eunice too, if you can believe that), but it's buggy: it thinks the values it's reading are doubles and not floats. But there's an even bigger issue: GNU coreutils is compiled with IEEE floating point (as it should be), while the LAVDRIVER returns VAX 32-bit floats.
Long story short, I realized that the LAVDRIVER.EXE that MultiNet provides was likely going to be inefficient if it's still written in VAX assembly, and I can hardly believe they would be using floating-point at all in the kernel. The more I looked at the problem, I realized it wouldn't be advisable, and perhaps not even safe at all, to touch the FP registers. Much better to use and return fixed-point integers, so that's what I did. I rewrote my own LAXDRIVER in C and it seems to work fairly well, at least on Alpha and Itanium (after many crashes and false starts on the Alpha, which is easy to get crash info from).
https://github.com/jhamby/vms-laxdriver
I've put it under an MIT license: it's all my original work, except for the skeleton and some of the function comments that came from the sample LRDRIVER.C in sys$examples that I used as a template (I'm sure VSI won't mind since they put the code there as an example). There's a test app you can compile as test-lav-driver.exe to read from the original VAX FP LAVDRIVER, or with /float=ieee to build as test-lax-driver.exe and read fixed-point with 14-bit scaling factor from my new driver.
I do have one apparent bug in the load average that I'm calculating, and without access to any internals docs newer than for V7.0, perhaps some changes have been made to the scheduler that I don't understand, so I'd be grateful for any insight into what's happening:
When I have 2 process each using 100% CPU on a two-CPU Itanium, the load average settles in at around 3.5 to 4.0, or rather fluctuates between those two. It should be much closer to 2.0, with two runnable processes and two cores (it's a bug in the original LAVDRIVER to divide the load average by the number of CPUs; no other OS I know of does that).
Relatedly, in MONITOR, I can also see 2 CUR and 2 COM at the same time. I don't understand how I could be seeing processes marked as CURrent in the per-CPU table and yet also counting the same process as COMputable. Is that a bug or do I need to do something more than hold the SCHED lock?
Regards,
Jake Hamby
More information about the Info-vax
mailing list