|Home » Resources » Rants
Why Trash Windows 98?
Week of March 21, 2000
Nearly every computer comes equipped with Windows 98 these days - why trash it?
One of the big disappointments with buying a home computer is finding out that your initial investment, despite the free CDs and everything else you get, won't even begin to cover your expenses. And one of the things you learn right away is that the machine is prone to instability and can cause you a lot of problems if you don't watch out. And one of the biggest perpetrators of all the headaches that can ensue for you is your operating system. It shouldn't be that way, but unfortunately, on the PC, in the world of Microsoft, it is. No matter how many add-ons you acquire that supposedly compensate for one or another weakness or shortcoming in the underpinnings, if those underpinnings are shaky, your machine will never be anything less. If the operating system is no good, all the good intentions and long nights of shareware downloads are not going to help a bit.
Many ISVs are only now learning how to support other Microsoft platforms, so the programs you enjoy the most might not even be available on anything else. But barring that, there is a lot you can do. Yet before you actually decide to 'take the plunge,' you should be in possession of as many pertinent facts as possible.
Personal computers run today on 32-bit processors. Being 32-bit means that the processor has 32-bit registers. A bit is a binary digit, and is an abbreviation of it, and the point is that the more bits in those registers, the more powerful your computer. If, that is to say, the programs, including the operating system running in your computer, can use all 32 bits.
Windows 98 only uses 16 bits of the 32. The last time the processor manufacturer Intel churned out a 16-bit processor was way back at the very beginning of the 90's - almost ten years ago. Almost ten years ago the PC world had the ability to get up to speed, so to speak - and only Windows has held it back.
But there's more to it than that. By the very nature of a lot of what is going on in your machine, 16 bits is not only slower by a geometrical factor, it's also a lot less safe too. Windows 98, which builds on 16-bit Windows for Workgroups 3.11 which shipped in the fall of 1992 (yes it's the same code base) is in many respects not only incredibly sluggish but highly unstable. Granted, the operating system proper might in fact be stable (in fact it is not, but that's not the argument here). It's just that this 16-bit dinosaur cannot assure that everything else running in the system adheres to the rules and is as stable as it should be too.
Many are the wonders (and griefs) of programming, and one of the classic nightmares is the runaway pointer. Sometimes a program gets off on a tangent, so to speak, and starts writing to the wrong addresses in memory - and keeps on going and going and going. A proper operating system, in the interests of self-survival, will be able to spot a runaway and stop it before anything disastrous occurs. But in the world of Windows nothing of the sort is possible. You'll come crashing down like a house of cards instead.
It's important to remember that Windows for Workgroups, the foundation of both Windows 95 and Windows 98, is not an operating system per se, only an application, with no more and no less rights than anything else running in the computer. 'Classic' Windows had to ask nicely to be able to perform its 'operating system' tasks, because it couldn't get hold of the processor and do anything unless the applications that were running permitted it. The Windows for Workgroups kernel has been extensively re-written for Windows 95/98 (and in 32-bit code too) to prevent as many mishaps as possible, but it cannot get at the core of the problem itself.
The core of the problem, ironically, is not Microsoft but the ISVs - all the other software vendors out there. Faced with an imminent (and gratifying) move to 32-bit code, Microsoft began to hound these ISVs to clean their act up. For years the ISVs had been writing extremely 'dirty' code and getting away with murder. Microsoft warned them that tricks like that would not work under a 'secure' operating system. But no one - in typical fashion - listened. The bug farms continued to sell well, and since when has a marketing suit ever looked twice to read the writing on the wall?
Faced with the alternate fate of OS/2, Microsoft made a strategic decision - the only possible one: let the bandits continue to run. An ISV base of over 30,000 applications was decisive - without these applications Windows might go to an early grave; with them it could survive and come out victorious.
The solution can be found in a memory map of Windows 98 as it runs today. To understand this map you have to understand how an application - how the system itself - looks at memory. Memory is no longer a question of how much RAM you have installed in your computer - it's a question of how many bits you have in your processor registers. Processor registers can be used to store addresses to bytes in RAM. The determining factor therefore is how many different addresses a processor register is capable of. With 32 bits a register is capable of 4GB (four gigabytes) of different addresses.
So that's how much memory you have in your machine - virtually speaking that is. You probably bought your machine with 64MB or 128MB at the most, but no matter the amount of installed RAM, Windows 98 and your true 32 bit applications will act as if there were four gigabytes (4GB) there instead.
These four gigabytes are only virtual memory, but they are very important. The operating system 'maps' different things into different areas of this gargantuan 'address space'. Your application is loaded normally at address 4 megabytes (4MB). If your ISV supplied you with DLL files for your application, they can often start loading at address 10 megabytes (10MB), and so on - virtually. Where these modules actually reside in RAM is another matter, and of no importance here whatsoever - for the purposes of the functioning of the operating system proper, and for your application, it is the virtual address space which means all.
The Magic Barrier
Applications run on Windows 98 map most things under the 'magic barrier', which is half way up the 4GB map at 2GB (this is also the magic barrier in vanilla MIPS-compatible NT by the way). 98 maps itself into the high gigabyte, between 3GB and the end of the map at 4GB - 'way up there'. But system DLLs and other paraphernalia are mapped into the area between 2GB and 3GB, and all your legacy 16-bit apps from Windows for Workgroups (or earlier) are mapped there too.
The 2-3GB area on Windows 98 is a special area. Being there gives you special privileges you won't gain elsewhere. Any code resident between 2-3GB on Windows 98 is allowed to do anything, read anything, and overwrite anything in the system.
Your system support DLLs - kernel32.dll, user32.dll, gdi32.dll, comdlg32.dll, comctl32.dll and so on - are all resident in this area and are mapped a single time for a complete Windows session, and all applications running will access the same code and data. In contrast to other operating systems where support DLLs are mapped for each client application, Windows 98 maps them only once.
Say you install a new shareware app and things go south immediately. You have to kill the berserk app. It seems to have left memory, but is everything really ok? Probably not - the very same system code (perhaps even system data) which the berserk app screwed up is still around and will be used by all your other applications, presently running or soon to be running, or both. If the berserk app ruins anything up there between 2-3GB, then something else is bound to happen any second and so forth - a spiral effect, with a blue screen of death as the only way out. And once anything resident between 2-3GB gets screwed up you've had it - this code has a carte blanche to corrupt anything in the system.
It's Not Their Fault
Don't blame Microsoft. A system that exists and can be used, however shaky, is infinitely superior to a system that doesn't exist at all (like OS/2). Without the 16-bit application base you might not have Windows 98 to run today, no matter how many 16 bits you have or do not have lying around. And Microsoft did really try to get the ISVs to clean their act up, but no one ever listened. For once, it is not Microsoft's fault.
Graphics are another area where you are going to suffer with a 16-bit OS, and the difference is not on a factor of 2, but on a factor of about 10. Using only half of the 32 bits in the registers slows down everything considerably. And don't forget - everything in Windows is graphics. There is no 'text mode' per se. And every window, every button, every combobox has to be 'painted' - meaning graphics and more graphics. Truly advanced graphics cannot be run on Windows 98 at all: mapping modes which use the full 32 bits are completely lost. Windows 98 will only see 16 of these bits and create a fettucine instead of a Da Vinci.
32-bit applications that run on Windows 98 are supposed to be able to run on big brother Windows NT and vice versa, meaning the platforms for these applications should be identical in this regard. But they're not, which brings up another matter. Unbelievable as it may sound, Redmond suffers from internal rivalries, to the point that programmers in the respective Windows 98 and Windows NT camps really set out to create problems for each other. The extended dialog template is a perfect example. This new template has nothing to do with so-called extended window styles, yet the 98 team has seen fit to disable extended window styles for all but the extended dialog templates. No client or static edges, no topmost, no inherent drag-drop, etc. - all because they refuse to budge on the issue, despite the standard being patently clear. Or take the tool help library - a wonderful implementation on Windows 98 to aid in the construction of debugging tools. It would have been a cinch for the NT team to port this code, but because they're already ensconced with NT's Registry performance key, nothing was ever done. The list goes on and on, and the punch line is that Microsoft demands that ISVs guarantee platform independence for their applications in spite of this.
And in general, what works wonderfully according to the documentation will work often strangely or not at all under Windows 98. The so-called Win32 programming interface is an incredibly rich and complex terrain, but in countless situations Windows 98 can do nothing about it but return a meaningless value for the calling application. There is no question of implementing any security features - Windows 98 has no security whatsoever. All processes, threads, events, mutexes, semaphores and other critical kernel objects should be capable of being bound by security descriptors, and not to satisfy the control thirst of some system administrator, but to ensure that the operating system and the applications running in it are not jeopardized by anything untoward that happens in one suspect app. But in this regard Windows 98 can offer absolutely nothing.
The specter of calamity continues as you begin to understand what has to happen to all those 'modern well behaved' 32-bit applications out there that want to run on Windows 98. True to the shrink wrap logo requirements of Microsoft, they use only 32 bit code, and exhibit the important 'portable executable' magic at the beginning of their image header. They both run only 32 bit code and only call modules written in 32 bit code. In fact, they have no ability to call 16-bit code at all.
But the bulk of Windows 98 is still Windows for Workgroups 3.11, which is 16-bit code, so what gives? The answer is thunking. This is a lovely word, invented perhaps in the Redmond camp, to explain the smoke and mirrors process whereby applications of different processor architectures can interchange calls. Initially the traffic originating on the 16-bit side was the most important: Microsoft tried to push its Win32s environment for quite some time, but to no avail. And even today, if you want to run an old 16-bit app on Windows NT, you need this feature. But it's the traffic starting from the other side which is the most interesting - and detrimental - to Windows 98. The traffic originating with all the well-written 32-bit apps that has to delve into the murky depths of the 16-bit Windows for Workgroups core.
Exactly how it's done is not important - that it takes a lot of time is. Every single function call - and programs are full of function calls, hardly anything else - has to be translated as it were - thunked - into a 16-bit call and sent 'over the fence' to the appropriate 16-bit module. The 16-bit module gets a 16-bit call, does a bit of calculation, and then tosses it back over the fence. The thunking layer picks it up again, transforms it back into 32-bit code, and returns it to the initial caller. All of this can effectively slow down an application by a factor of much more than two, function calls per se being one of the most expensive operations your software ever performs.
But there's more. A system running old 16-bit Windows for Workgroups code is inherently unstable (yes much more so than Windows 98). In fact, just letting things be while 16-bit code is running in the machine is inviting disaster. So to avoid any excess damage, Microsoft implemented what is known as the Win16Mutex.
A mutex is a rather 'heavy' synchronization object. And a synchronization object is an object which can force the computing code in your machine to stand still and wait - be blocked - if the object is not properly set. The name 'mutex' is a contraction of 'mutually exclusive', which should go a long way to revealing what it's all about.
Only one bit of executing code (one thread as it's called) can 'own' a mutex at any one time. These 'threads' in all the running applications vie to get ownership of the mutex and are politely put in a sleep state by the operating system until their turn comes. They use no processing power to speak of while they are sleeping, so there is no performance trade-off here. But the actual implementation of a mutex requires very secure routines at the bottom of the operating system and thus is regarded as quite 'heavy', i.e. requiring a lot of processing power.
When any 32-bit application running on Windows 98 calls any one of the thousands of functions in the operating system interface (which is about all applications seem to do), the executing thread starts out by trying to get ownership of Win16Mutex. Until it does, the code running in the application is actually 'sleeping'.
Only one thread in all the applications running on your desktop may venture into 16-bit territory at a time. This sounds more innocuous than it is. Threads are 'time sliced' back and fro in and out of the processor - they run only small chunks of time called quanta (or 'time slices') and when their time is up, so to speak, they are butted out of there and another thread gets access to the processor instead - thus supporting the illusion that 'everything is happening at once', in other words, the famous expression 'multi-tasking'.
But simply because a thread that has inadvertently called 16-bit code from the Windows for Workgroups core is kicked out of the processor at the end of its current time slice does not mean that it has relinquished the coveted Win16Mutex. No, on the contrary - until the thread in question explicitly gives up ownership of the Win16Mutex (or dies) no other thread in any other application can do a thing. Not squat. Nada. Diddley. Scratch. Rien. Nichts. Nichevo. Nothing. The system - imperceptibly to you on this level but noticeable in the long run by virtue of the general sluggishness - simply stands still.
And if only that were now the end, but it is not. No developer was unaware of the coming dependency on Windows for Workgroups in the Chicago project, despite claims that it all came as a surprise. Someone had to start somewhere - and the most important thing was to get all the ISVs migrating their code to 32-bit as soon as possible. But back then we hadn't heard so much from Andrew Schulman either. Andrew had a forum back then at MSN and in it he disclosed some cute facts about the coming Chicago release.
Old DOS used something known as a program segment prefix (PSP) to run applications. This little 256 byte chunk of data contained important squigglies for getting the operating system back in control when the application had exited and so forth. What no one knew - until Andrew Schulman clued the world in that is - was that Windows 95, that foray into the stable world of 32-bit programming and 32-bit operating systems - was still using the PSP mechanism straight out of the old DOS code to run 32-bit applications.
Meaning exactly what? Well, besides the esthetic disappointment ('couldn't Redmond be a bit more creative and ambitious?') there were a number of potentially dangerous scenarios connected with this PSP. The PSP had to reside in 'low memory', the kind of memory DOS could see, that is to say memory addresses under 640KB. Which, coincidentally, was also where all the 16-bit and 8-bit drivers had to reside. And where, for that matter, any fixed memory allocations would end up sooner or later.
So let's say we have Joe Geek, home with his new Pentium IV 2000Mhz 2GB RAM super machine, and he's trying to run any number of drivers and applications all at once, and when he starts up an old copy of Winword and tries for a print-out he sees the message box:
'Your system is running low on memory. Close one or more windows and try again.'
'Woah!' says the computer literate Joe Geek. 'I got two gigabytes of RAM in this sucker! What's up?'
The PSP is up is what. Good old Windows 98 tried to find a paltry 256 bytes free memory under the 640KB barrier to start the Winword printing process and failed. All the drivers and other applications and memory allocations had already taken all the real estate there. Sorry, Joe.
Which all makes for a wonderful computing experience. Windows 95/98 were never meant to be durable platforms, only bridges from the world of 16 bits into the far better, faster, and more secure world of 32 bits. But something happened along the way - the ISVs happened - and with all those games, and all that Plug 'n' Play, that Macintosh kind of experience, and the prospect of a sales boom in home computing, it found its own niche and began to look like a product in its own right.
Windows 98 doesn't really know how to treat a gift horse either. Adding lots of RAM onto it will not make it run significantly faster. About all that will help here is a faster processor - but faster processors are far more expensive than the RAM necessary to boost a true 32-bit operating system by the same factor. Tests conducted in Germany after the release of Windows NT 4.0 showed that Windows 95 could stay on the same lap of the track only as long as the 95 and NT machines were not given 32MB RAM to work with. When both had 32MB RAM or more, NT pulled away - defiantly. Studies at Radsoft about the same time showed that in many respects Windows 95 could not avail itself of anything above 24MB - something like a high barrier when it came to system paradigms. All this MMX technology and the equivalent is like putting an afterburner on a motor scooter.
And Now For Something Totally Different
Meanwhile, in another building in Redmond, some unfamiliar faces were hard at work doing goodness knows what. They were not Microserf recruits - they had come from somewhere outside the company, and they might have been a bit intimidating at that. Even Bill, it was rumored, was afraid to get too close. This was David Cutler's NT team, brought aboard in the end of the 80's, before Windows was anything more than the traditional abject failure it had always been, while OS/2 was still the best program ever written on the planet Earth. Cutler had been with Digital Equipment for the RSX, VMS, Mica and Prism projects - the latter, based in nearby Seattle, having only recently been abandoned. Dave had always wanted to re-code VMS in C, and now he had his chance. Working initially with Intel 860's and targeting this platform as well, Dave and his team built a character mode network file server operating system. Gradually, as people started clarifying objectives out there, a GUI was added on top. But the GUI code that Dave and his friends used came initially from the buggy Win16 camp and could therefore not be used directly. It had to be worked over to adhere to 32-bit computing intrinsics. And in this process, under the inspection of seasoned developer's eyes, it grew. This was no mere hack, even if the source might have been that. The people at the top of the Cutler pinnacle were not the product of the Microsoft experience. They came from Digital Equipment, UNIX System Laboratories, Carnegie-Mellon University, and Hewlett-Packard. They had their own opinions - something otherwise almost illegal in Redmond. They basically knew what they were doing. And it showed in their coding too.
NT made no compromises to ISVs who didn't want to write clean 32-bit code. NT was made to pass Department of Defense Orange Book criteria for safe and secure operations. And the assembled team with its experience of historical mishaps could take measures to see that the old stuff didn't happen again. Trojan horses are a perfect example. These treacherous animals were the nemesis of UNIX systems everywhere, so they figured out a way to keep the horses out of NT: the secure access sequence (SAS). The PE format is another example: building (and improving) on the UNIX COFF, it took everything a step further so that executable files on disk would be set up exactly as they needed to be mapped into memory at runtime, so that you had the curious situation of an application using its own image file on disk as its virtual memory backup.
Then there's discretionary access control - meaning if you want to, you can prevent others from accessing your files, directories, Registry information, etc. On a 98 box anything is game, and anyone can get at anything. But NT had to be a secure system.
Clean memory is another point. No application (process) should be able to overwrite or even read the memory of another process, or even peek into the memory left behind by it when it exits.
Together these three criteria constitute 'C2' level security in the DoD Orange Book and very good security indeed, better than what many other operating systems have, and with benefits reflected in ease of use for both the developer and the end user.
Since NT uses its own file system (NTFS), the days of the 64KB cluster are gone forever: when transitioning to NTFS you cut disk waste by a factor of 100 or more. The first time a system administrator converts a FAT disk to NTFS and sees how much disk space is freed - it's a precious moment, a true 'aha' experience. NTFS is slower than FAT to be sure, but it's also a lot safer and more secure, and in the event of a system crash, there is less chance your disks will be harmed.
NTFS is a transaction based file system. Every proposed file operation - a rename, a delete, a move, a copy - gets put into a transaction log for starters. Along with the details of the file operation goes complete 'undo' information - i.e. if anything goes wrong with the operation, NTFS wants to know how to get things back to where they were in the beginning.
Running along side this transaction log is an 'atomic' pointer which indicates at any one given moment just how far along the transaction log the file system driver has got. Say you start copying a 25MB file when the lights go out. On Windows 98 your disk would be a mess, but not on NT. For only when a file operation has completed successfully will the file system driver advance its pointer.
It's like a check list if you will. '25MB file, copy to drive C: - check! File 'My Documents' - rename to 'Our Documents' - completed. Check!' And so forth. If any operation should be interrupted before it is completed, the position of the transaction log pointer will tell all - NTFS will know what the last attempted operation was, how to completely undo it, and how to thereafter start all over again to 'redo' it. NTFS disks rarely run into trouble.
The Need For Speed
Whatever else you hear - NT is fast. At least compared to 98. The graphics are faster by a factor of ten. It avoids all those horrible mutexes and that dusty Windows for Workgroups code. And it is scalable, at least to the extent that it can use all the RAM you can throw at it. NT has a very sophisticated memory management system, whereas it's difficult to describe what 98 does as memory management at all. And most important of all: NT almost never crashes. At least nothing like 98, which seems to want to go down all the time. People can keep NT running on their desktops for days and weeks without a re-boot. Try running 98 for a whole day without a re-boot and see what happens.
NT is cheap too - at least today, at least with the market the way it currently is. 98 out of the box will cost you about $70 - you can get NT 4.0 for half that price. True - if you took your new computer home with 98 already installed it's a $35 diff in the other direction, but once again it's a question of getting your system up and running properly, not the incidental and marginal $35 it would cost you to set things right once and for all.
You don't need Win2K. Most corporations are smarter than to upgrade to this monster right away, if at all. Stability in the market is desirable, especially when news of new Win2K bugs are drowning the media. NT 4.0 will run nicely on your desktop machine for years to come.
All told, you can probably run NT on a much older machine than you can 98 - provided you give it enough memory to compensate. Yes, NT wants more memory to start with - but it can do so much more with that memory once it's installed. Nowadays no one is marketing boxes with 16MB anyway. A low level Pentium with 32MB RAM will run NT 4.0 very well.
There's a bit of a learning curve when it comes to NT, but it's shorter and not at all as steep as people would have you believe. The two interfaces to 98 and NT are intentionally similar - technically this is an adherence to what is known as the Recognition Principle of IBM's seminal Common User Access standard - NT was so loyal to ordinary Windows in the beginning that its first version number matched as well - 3.1. Where you will see differences you will also for the most part notice increased functionality and more dependability.
Some day you might want to try on something even more challenging, such as Linux. Linux can be the ultimate treat, and might prove to serve you even better, but in the meantime, while you're still not sure of how you want to run that Cray Mark IV PDA you brought home last weekend, give a thought to NT. You won't be sorry you did.