> They used to work very hard to make sure updates didn't break popular programs that used undocumented hacks.
Obsessively.
I worked for a company that sold a security auditing tool. We cared very much about which version of Windows we were running on. When Microsoft came out with the next version of Windows and to our dismay, we found out that our software recognized it as the old version.
Turns out that Microsoft had found (pre release) that the new version broke our software. It reported "unknown version" or something. So they added us to a long list of applications that, when those applications asked for what version of Windows they were running on, Windows lied and told them an earlier version.
It cost us some heartburn to work around Windows trying to be helpful to us...
I frequently implemented this from the other side at Apple.
You'd be shocked at how much software enables features based on a `==` OS version check. When the OS bumps its version, the software regresses to some earlier behavior. Lying to the app is the simplest way to keep it working.
So sad to see Alpha die off, especially since I haven't noticed any architectures with anything like PALCode spring up since. The Alpha's firmware was essentially a hypervisor that only supported a single guest, and the OS kernel had to upcall to the firmware for any privileged operations.
In particular, it would be nice to have userspace programs be able to take advantage of new/larger registers without requiring the OS kernel to support the extra CPU state. If the firmware (which presumably is available as soon as the new CPU ships) handles the context switch, then the OS kernel doesn't need an update.
On the other hand, Alpha had an infamously weak memory ordering, and it dying means that we don't have to deal with that when writing software. Check Documentation/memory-barriers.txt on the Linux kernel for the gory details (recent versions are after the kernel was changed to make Alpha work somewhat more similar to other architectures; check that documentation file on older kernel versions for the full horror).
Yes, I'm familiar with the woes of the particularly weak memory model. It's mostly a problem when writing lockfree data structures, as mutex acquisition and release executed the necessary fence instructions to maintain proper happens-before relations.
PAL code didn't do anything like context switches and I'm not sure how it could, given how the OS needs to know the specifics of the thread context in many scenarios.
That's correct. On NT/Alpha context switching was done in ntos\ke\alpha\ctxsw.s, which was regular kernel mode assembler code. A PAL call was made but it simply set the new Teb and Pdr; two or three lines of code. I've never seen the PALcode for VMS or OSF/Tru64 but the NT PAL for swpctx was designed so that alpha assembler code in NT looked as much like the mips code that davec wrote. It made the port easier that way.
Interesting Raymond continues to mention NT/Alpha now and then. If you run into him mention I have a collection of NT/Alpha artifacts and anecdotes he might be interested in.
I believe in the specific case of L4/Alpha, the PALCode did perform the context switches. Granted, I doubt it was as robust as the VMS or Tru64 PALCode versions that were production-ready.
PALcode implemented context switches for all systems, including Linux (which uses Digital Unix PALcode). Specifically, PALcode covered various internal details of the CPU presenting unified interface to OS - each CPU needed custom PALcode implementation, though IIRC there were only few mandatory PALcode calls (related to memory barriers, iirc). The kernel covered switching OS-specific structure pointers over, PALcode handled all sorts of MMU, TLB, PASID indexing of TLB, internal CPU state etc.
L4/Alpha PALcode was limited to specific set of CPUs it was implemented for, so unlike VMS, NT or Digital Unix PALcode it wasn't available outside of those few machines.
They used to work very hard to make sure updates didn't break popular programs that used undocumented hacks.