Cover Story (sidebar) / August 1995

The Elegant Kludge

Windows 95 may push the Windows 3.1 architecture as far as it can go

Randall C. Kennedy

Windows 95 is a remarkable evolution of the Windows architecture. Its new interface is easy to customize and navigate. It runs 16- and 32-bit applications better than ever. It also has such advanced features as Plug and Play and built-in networking. There is no doubt that it will make the lives of millions of PC users better.
 
Yet despite the advances that Windows 95 represents, there are still Windows 3.1-isms. For most users, these architectural anachronisms may mean nothing more than an occasional unexpected crash. But they also lend tremendous weight to Microsoft's assertion that Windows NT and not Windows 95 is the preferred solution for advanced business users, who need security and superior crash protection.
 
View from 10,000 Feet
 
Microsoft has done an impressive job flushing out the features list for Windows 95. It has probably the best support for mobile computing of any OS, the built-in communications features are extremely impressive, and it offers a fix to the long-standing complaint that Windows will run only a few applications before stating that it doesn't have enough memory.
 
Portable computer users will love the much-vaunted Plug and Play technology. Although it sometimes has problems dealing with legacy hardware in ISA-bus PCs, Plug and Play works wonderfully on notebooks with PCMCIA slots. Plug in your card, and the built-in 32-bit card and socket services recognize it and automatically load drivers for it (prompting you for disks if it needs new drivers). Unplug your card, and the drivers unload.
 
Similarly, Windows 95 tracks whether your notebook is docked or undocked and loads appropriate drivers. So, for example, when you go into the office and dock your machine, Windows 95 knows that you're connected to an external monitor and runs at a higher resolution. Undock, and it knows that it should be running at a lower resolution.
 
Users on the go will also like the Briefcase, a file-synchronization tool built into Windows 95. When you leave your office, you can pack the Briefcase with the files you need and load it onto a notebook. When you return, simply load the Briefcase back onto your desktop and synchronize the contents. Windows 95 examines the individual files for changes and automatically updates your originals to reflect work done outside the office.
 
Windows 95 is also a great communicator. If you're on a LAN, you'll find that Windows 95 not only supports all the common network protocols and adapters, it makes them easy to manage through a simple control panel applet.
 
For telephone-based communications, you have Microsoft Exchange. The bundled Exchange client, which includes fax, E-mail, and Microsoft Network subsystems, provides many features that you had to purchase separately under previous Windows versions. For example, the Microsoft Network client will enable on-line software distribution and technical support.
 
Finally, a redesign of Windows 3.1's 64-KB resource heaps enables you to run more applications before you encounter out-of-memory error messages. For example, with Windows 3.1, you could generally run three to five applications at once. With Windows 95, you can generally run a mixture of six to 12 DOS, 16-bit Windows, or 32-bit Windows applications.
 
Fixing Problems
 
Windows 95's stability, networking support, and user interface are unquestionably improved compared to DOS and Windows 3.1. But they aren't all at the level that users of OSes such as OpenVMS, Unix, and even Windows NT expect.
 
One of the problems in Windows 3.1 is that a single application can crash the entire operating environment, forcing a reboot. Similarly, Windows 95 bares much of the OS's core to running applications. For example, the critical USER and much of the GDI (Graphical Device Interface) code — which provides window management and graphics services to applications — is still 16-bit and runs in the same address space as 16-bit applications. A buggy 16-bit program can potentially hang the virtual machine in which USER and GDI run or, worse still, stomp all over USER and GDI themselves, bringing the system to a halt.
 
Even 32-bit applications can bring the system down. Much of the lower 1 MB of the Windows 95 system code's address space (i.e., the System VM) is wide open to operations by Win32 applications.
 
Multitasking is another potential sore spot. Windows 95 routes all USER API calls through the 16-bit System VM, which is also where 16-bit applications execute. If a 16-bit program hangs the System VM by refusing to process messages (the most common type of failure among existing Windows applications), all other processing eventually comes to a standstill. Until you clear the errant 16-bit program (Windows 95 has a good facility for killing it) and thus free the System VM, other running programs — even 32-bit ones — are blocked from executing.
 
Finally, there's Windows 95's new GUI, which is different. Most users think it's an improvement. But if you're in charge of IS, even if you ignore the retraining costs associated with a wholesale change in the GUI, there are holes in the Windows 95 object-oriented implementation that can be annoying. The lack of a SOM (System Object Model), such as the one in OS/2, is a good example. With no centralized object manager to track object interdependencies, links between visual elements and the underlying file system are fragile. Thus, if you move a file to another volume, all shortcuts to it are broken. Similarly, if you rename a DOS executable file from a DOS prompt, you'll get the same result.
 
Ghost in the Virtual Machine
 
Under Windows 3.1, a simple, protected-mode, 32-bit VMM (virtual machine manager) runs the show. You probably know this as WIN386.EXE, that large executable file sitting in the SYSTEM subdirectory of any Windows 3.x installation. WIN386's job is to juggle the various Windows VMs — the System VM and any VDMs (virtual DOS machines) — to make Windows 3.1 work.
 
The key component the VMM manages is the System VM. It's essentially an extended VDM. The System VM provides DPMI-based (DOS Protected Mode Interface) extended memory to all running Windows applications. Windows applications execute in the System VM, in a shared address space stretching in linear memory from 2 to 4 GB. This shared VM also houses the window management (USER) and graphics (GDI) subsystems, as well as any VxDs. In essence, Windows 3.1 operates in one chunk of memory.
 
This model still applies under Windows 95 — with some modifications. Like Windows 3.1, all 16-bit Windows applications execute in a shared address space in the upper 2 GB of linear memory. However, to provide support for 32-bit Win32 applications, Windows 95 modifies the original VMM in two ways.
 
First, Windows 95 revises the linear-memory map of the OS. It exploits the region from the lower 1-GB range (just above 4 MB) up to 2 GB to provide an address space for Win32 processes. Win32 applications are mapped into this region at run time and make their API calls to subsystems and VxDs located in the upper 2 GB. The result is a 4-GB address space for the Win32 application — the lower 2 GB for the program's own code and data, the upper 2 GB for the OS. This configuration is similar enough to Windows NT that Win32 applications will execute on either platform (with a few exceptions, most notably applications that rely on NT security APIs).
 
But applications compatibility is where these similarities end. Under Windows NT, each process is isolated in its own private 4-GB VM. API calls are intercepted by subsystem "stubs" located in the upper 2 GB of the address space and sent through a special message-passing mechanism in the Windows NT Executive (the local procedure call facility). They are then processed by the real subsystems that reside safely in their own isolated VMs. This protection model is remarkably secure, which makes NT extremely hard to crash.
 
Windows 95, on the other hand, loads each Win32 program into the System VM. As a Win32 program executes, its address space is also the address space of the System VM. Here's what goes on there. The upper 2 GB contains most of the Windows 95 subsystems, including the system and network cache, while the lower 1 MB contains the real-mode DOS image from boot time as well as parts of the 16-bit Windows subsystems (i.e., USER, GDI, and KRNL386).
 
This model enhances performance because all the code is running in the same VM, eliminating costly local procedure calls. But it also increases the risk of a debilitating crash because the Win32 program can write to almost all of the upper 2-GB and lower 1-MB regions.
 
The second way in which Microsoft modifies the Windows 95 VMM is by adding support for threads within Win32 applications. A multithreaded application appears more responsive to the user by breaking itself up into small pieces, each of which can be scheduled independently by the OS's scheduler.
 
Multithreaded applications assume a preemptive multitasking model. In other words, the OS should be able to schedule when applications will have the CPU's attention. But this is not always the case with Windows 95. Although the VMM scheduling is itself preemptive, it's still at the mercy of 16-bit Windows applications because the OS relies on 16-bit code in key areas. To retain a high degree of compatibility, Microsoft kept some of USER and GDI 16-bit. Existing 16-bit Windows applications interact with these modules directly, as they do under Windows 3.1. API calls from Win32 applications first go through a thunking layer that translates them into 16-bit format.
 
The code used in these 16-bit modules is based on the same single-tasking, nonreentrant code found in Windows 3.1. To protect these sensitive structures from overloading in a preemptive environment, the designers of Windows 95 serialized access to them. Only one task can execute in the 16-bit USER or GDI modules at a given time — all other processes are blocked until the program either finishes with the code or is preempted by the Windows 95 scheduler.
 
When dealing with Win32 applications, Windows 95 indeed behaves like a preemptive multitasking OS. But, because 16-bit Windows applications weren't designed to be preempted — and most break when you interrupt them improperly — Microsoft kept Windows 3.1's cooperative multitasking model when executing 16-bit applications under Windows 95.
 
In a nutshell, when a 16-bit program executes, all other programs are blocked from running until the 16-bit program "yields" (slang for making one of the known API calls that let the Windows cooperative scheduler switch tasks). This is true even of Win32 programs. Although they are preemptively scheduled and exist in their own address spaces, they must still make API calls to the 16-bit USER and GDI heaps. As long as a 16-bit program is executing, access to USER and GDI is blocked. If a 16-bit program hangs, all processing will eventually halt as thread after thread blocks on the unavailable USER and GDI.
 
In addition to the changes to the VMM, one of Windows 95's most highly touted features is support for a 32-bit file system called VFAT (Virtual File Allocation Table). It is based on the FAT (file allocation table) file system that DOS has used for years. Windows 95 moves the code into protected mode, implements it in 32 bits, and, through a clever use of extra, hidden directory entries, adds support for long filenames.
 
The first two points affect performance — VFAT, like 32-bit File Access in Windows for Workgroups 3.11, screams. The last point, long filenames, benefits the broadest range of users. No longer do you have to truncate document descriptions to fit the eight-dot-three straitjacket of DOS's FAT implementation. Windows 95's long filename support is compatible with Windows NT. You can dual-boot the same system and gain access to long filenames in both environments.
 
In terms of the big picture, VFAT is the first product of Microsoft's efforts to modularize Windows. Under Windows 3.1, disk I/O was handled by DOS (with a little help from the BLOCKDEV and INT13 VxDs). While effective, this model was monolithic and tied to FAT devices. Under Windows for Workgroups 3.11, Microsoft laid the foundation for VFAT by changing to an IFS (installable file system) model. File system drivers plug into the IFS Manager, letting you add new file systems at will and making the environment more extensible. In a way, WFW's IFS was a kind of dry run for Windows 95's VFAT.
 
In theory, you should be able to plug just about any file system into the Windows 95 IFS model. In practice, this isn't as easy as it sounds. Advanced file systems often include security or other platform-specific functions that would be difficult or impossible to support under Windows 95. IFS's most compelling use will likely be as a method to get nonstandard storage media — and in some cases, network transports such as NFS — to work better under Windows 95.
 
Inside the Whale
 
It's the people who will see the innards of Windows 95 the most (mostly programmers writing VxDs) who will have the clearest picture of the differences between Windows 95 and Windows NT. That's where you see how the OS protects sensitive memory areas.
 
When you look at the world from the vantage point of an Intel CPU, you see it as a series of programs running at different privilege levels — or protection rings — within the scope of the memory management scheme. At the very heart of the environment is the kernel, which is the first program to take control of the CPU.
 
Under Windows 95 and Windows 3.1, the VMM is the kernel. The core OS services (the VxDs) execute beside it in ring 0, while applications (DOS, Win16, and Win32) run in ring 3. In Windows NT, the kernel is part of the Executive, a set of core OS services that run at ring 0 — the most privileged level of the CPU's memory and execution scheme. As with Windows 95, Windows NT (Win32) applications run in ring 3.
 
Because they run in ring 3, applications aren't as privileged as the kernel or other core OS services. For example, the VMM can deny them access to certain hardware resources or force them to go through VxDs. Consequently, it's harder for them to crash the entire OS than it was under Windows 3.1.
 
Windows NT doesn't allow anything into ring 0 except the OS. But Windows 95 runs VxDs there. In addition, to maintain compatibility with Win16 and DOS applications, Windows 95 fails to exploit all the CPU's available protection mechanisms. For example, Windows 95 lets DOS programs directly control interrupts, improving performance but also potentially hanging the entire system if a DOS application goes south.
 
Win32 applications can also cause problems. To maintain compatibility with Win32 programs written for Windows NT, Windows 95 maps them all into the same address range in linear memory — 0 to 4 GB. Although parts of this memory are protected (the lower 64-KB region), other parts aren't (e.g., the upper 1-GB region).
 
This means that a Win32 application has complete read/write access to VxDs such as the IFSMgr (installable file system manager) or VCACHE (the protected mode disk and network cache). In a perfect world, Windows 95 could conceivably protect this sensitive upper 1 GB by making all its pages read only, but this in turn would break any 16-bit Windows applications that directly manipulate VxD data (a common occurrence).
 
Thunk
 
Thunking is the term used to describe how Windows 95 lets its newer, 32-bit components talk to its older, 16-bit components. Getting these two worlds to communicate is no trivial task. The 16- and 32-bit versions of the Intel protected mode are very different environments, and code written for one cannot simply call on code written for the other.
 
To begin with, the packaging of the API message parameters are different: 16-bit programs communicate using the 16-bit wParam and lParam variables, while 32-bit programs communicate using a 32-bit wParam. Similarly, the memory addresses specified in these message parameters must be reformatted to the scheme in use by the receiving program (32-bit for Win32 programs, 16-bit for Win16 programs and USER/GDI).
 
There must be a conversion mechanism, which is exactly what a thunk is: a mechanism for converting 32-bit API calls into 16-bit and vice versa. In Windows 95, thunks facilitate communication between the 16- and 32-bit sides of the OS. Each major 32-bit component in Windows 95 has a 16-bit counterpart. For example, USER32 works in conjunction with the 16-bit USER in the System VM (which is also the source of numerous bottlenecks). Similarly, GDI32 thunks down to the 16-bit GDI. Even KERNEL32 thunks down to the 16-bit KERNEL for many functions, such as managing current drive and directory information.
 
Beyond that, every single Win32 application has a corresponding data structure stored in real-mode DOS conventional memory. When a new program (Win16 or Win32) is launched under Windows 95, the Create Process API call — generated by KERNEL32.DLL — is thunked down to the 16-bit KERNEL, which in turn creates a new TDB (Task Database) entry for it in the 16-bit side of the environment.
 
The creation of TDBs under 16-bit Windows requires that KERNEL call all the way down to good old real-mode DOS, which then creates a corresponding PSP (Program Segment Prefix) entry in conventional memory. This sequence occurs for both 16- and 32-bit applications, with the only exception that the TDBs for Win32 programs are stored in extended memory (but their PSPs are still created and managed in conventional memory).
 
The practical ramifications of this design are twofold. First, because all running applications have a corresponding real-mode PSP, and because PSPs take up conventional memory, Windows 95's ability to run large numbers of applications is directly affected by the amount of available conventional memory your system has at boot time. (Sound familiar?) Second, with thunking going on, you have to wonder what the impact is on performance.
 
Windows 95 does a relatively good job of streamlining the thunking layer's performance. For most tasks, you shouldn't see any serious performance penalties. And because the only benchmark platform against which you can measure Windows 95's Win32 applications performance is Windows NT, and because Windows NT uses a more demanding client/server execution model, it's nearly impossible to determine just  how well a Win32 program might execute in a fully 32-bit setting that isn't a client/server one.
 
You're most likely to see the real bottleneck under Windows 95 in the serialized 16-bit USER and GDI code and, to a lesser extent, KRNL386. While thunking probably won't hinder Windows 95 performance, these 16-bit bottlenecks might.
 
The Bottom Line
 
Despite any engineering compromises made by its tough requirements for backward compatibility, Windows 95 has some engineering feats. Dynamically loadable VxDs, Plug and Play support, and a new interface make it a compelling upgrade.
 
But many of Windows 95's other "new technologies" are merely adaptations from previous Windows incarnations. The ISF, most of the core VxDs, and even the VMM itself have their roots in Windows 386, a 1988 product. (We will be reviewing Windows 95 fully in an upcoming issue.)
 
Our verdict: If you play games, want a near guarantee of backward compatibility, or want incredibly complete driver support for your hardware, Windows 95 is the OS for you. If reliability or multitasking performance are more important to you than a slick interface and Plug and Play support, you should seriously consider Windows NT and whatever hardware purchases that upgrade would require. Microsoft is moving toward an all-Win32 world as fast as it can, so, unless you're a serious game player or have applications or hardware not supported by Windows NT, it might be better to bite the bullet now and switch to a fully 32-bit OS.
 
In any event, you should be running tests on Windows NT to determine what it does well for you and, if you're in charge of any number of computers, whose you should consider upgrading.

Windows 95: Head-to-Head

  Windows 95 Windows NT 3.51 OS/2 Warp Connect
Preemptive multitasking of 32-bit applications Yes Yes Yes
Preemptive multitasking of 16-bit applications No Yes Yes
Multithreading Yes Yes Yes
Protected subsystems No* Yes Yes
Fully reentrant design No Yes Yes
Multiple DOS virtual-machine configurations No Yes Yes
Object-oriented interface Yes No Yes
Dynamic object tracking No No Yes
Long filename support Yes Yes Yes
Cross-process OLE (32-bit) Yes Yes No
Support for Win32s applications Yes Yes Yes†
Support for Win32 applications Yes‡ Yes No
*Windows 95 doesn't protect most of the system's address space from 32-bit applications.

†Up to Win32 version 1.15 (version 1.20 includes 32-bit OLE support so it doesn't work under OS/2).

‡Provided they don't use any NT-specific security APIs.


Comparative Architecture: Windows 3.1

Comparing the designs of Windows 3.1, Windows 95, OS/2 Warp Connect, and Windows NT 3.51

All four OSes run 16-bit Windows applications. All four can run 32-bit applications (albeit not necessarily the same ones). But they each have different ways to ensure that the applications run. The Windows 3.1 architecture is probably the easiest to crash; Windows NT's architecture is probably the most secure. Here's why.

Windows 3.1
                  architecture
Windows 3.1
Under Windows 3.1, there is one System VM. When you look at the memory map, you can see what that means: All applications run in the same address space. In addition, the DLLs that provide OS services run in this same memory space. With this architecture, if one application crashes, it's likely that all of Windows will crash.

 
Windows 95
                  architecture
Windows 95
Windows 95 modifies the Windows 3.1 model a little. Much of the OS's code still runs in the same space as your applications, but Win32 applications are run within private address spaces, which decreases the likelihood of one bad application crashing all of Windows 95. Notice that DOS is still in the bottom 4 MB of memory, along with USER, GDI, and KRNL386. Not that much seems to have changed.


OS/2 Warp Connect
                  architecture
OS/2 Warp Connect
OS/2 does things differently. For example, 32-  and 16-bit applications run in separate VMs, so it's difficult for them to step on each other. You also have the choice of running Win16 applications in either the same or separate memory spaces, making it difficult for them to step on each other. Of course, the OS's core services are largely protected from bad applications.

 
Windows NT 3.51
                  architecture
Windows NT 3.51
NT uses a client/server architecture unique among these OSes. Hardware calls and other low-level manipulations are virtually impossible with this setup. Applications must instead invoke services via local procedure calls. While extremely secure, this configuration slows some performance, particularly in games, which like to write directly to hardware. Like OS/2, Win32 and Win16 applications run in separate memory spaces, and you can choose whether Win16 applications will run in the same or separate memory spaces.
 

Windows 95 Pros and Cons

Windows 95 pros and cons.

INTERFACE PROS
Windows 95's interface fixes some of the complaints about Windows 3.1. For example, switching from application to application is now easier thanks to the Task Bar at the bottom of the screen. You can now place icons directly on the desktop. Also, the right-mouse button generally calls up a Properties menu.

INTERFACE CONS
There are some inconsistencies in the Windows 95 interface that will irk some users. For example, you can't right-click on the Start menu to reveal its properties. Nor can you drag items to the My Computer icon or the Control Panel, Printers, or Dial-Up Networking folders.

Randall C. Kennedy is coauthor of the forthcoming Windows 95 Bible and author of Migrating to Windows NT. You can reach him at rck@dnai.com or editors@bix.com.

Copyright 1994-1998 BYTE

Return to Tom's BYTE index page