Windows 386 enhanced mode takes advantage of the paging hardware on 80386 and above CPUs to implement virtual memory (see Figure 9). When running in this mode, two memory managers are present: the 386 control program, WIN386.EXE, and the Windows kernel, KRNL386.EXE.
The enhanced mode kernel uses the protected mode LDT to manage system memory in the same way as the standard mode kernel. But instead of referencing physical memory, the enhanced mode LDT references into a virtual address space that can be up to four times as large as the available RAM. The kernel treats the virtual address space as the global heap that it manages.
The second memory manager, WIN386, is responsible for supporting this virtual address space. It does so by enabling the paging hardware built into the 80386 chip. The paging hardware makes use of memory tables that are similar to the LDT, but which operate at a lower level: the paging tables. The paging tables translate a 32-bit linear address into the actual physical addresses for a page of memory. When a page is accessed that is not present, a page fault occurs. At that time, the virtual memory manager runs to disk to find the needed page. It loads it into memory, fixes up the page tables to reflect the changed system configuration, and restarts the machine instruction that actually caused the page fault to occur. This way, virtual memory is entirely transparent to the software.
Like virtual memory systems built on mainframe computers, the virtual memory of the 386 control program simulates a large linear address space by shuttling 4Kb pages between disk and RAM. The amount of virtual memory that can be created is limited by the disk space that is available for swapping, and by a limit built into the 386 control program that supports a virtual address space that is up to four times the available physical RAM. Therefore, with 5Mb of RAM and enough swap space on disk, a 20Mb virtual address space can be created.
One feature of Windows 3.0 is that the enhanced mode kernel does not start to discard objects until it has reached the limit of the virtual address space. Although this means that the 386 control program may swap discardable objects, it is faster to page out discardable data than it is to reload and relocate an entire segment.
Protected Mode and Memory Locking
When running in real mode, programs must continually lock and unlock dynamically allocated segments. The reason, as I mentioned earlier, is that segments cannot be moved when locked. Since moving segments is crucial to the health and well-being of system memory, programs must not lock segments any longer than they have to.
The situation is different in protected mode. Once a segment is allocated, it will retain the same logical address even though it may change physical locations in system memory. The logical address, after all, contains an index into a descriptor table. A memory object can be moved in protected mode by simply updating the corresponding entry in the descriptor table. Thus, the Windows memory manager can move memory in a manner that is completely transparent to applications.
Windows programs running in protected mode can do something that is inconceivable in real mode: keep data segments continually locked. This means you can lock a segment immediately after you allocate it to retrieve the segment's logical address. You can keep the segment locked as long as you need to and not bother to unlock the segment until you are ready to free the memory object. Since this will not interfere with the management of system memory, you are free to use this approach without fear that you will somehow disrupt the system. Of course, to do this safely, you must first check the GetWinFlags routine to make sure that you are running in protected mode. Also, keep in mind that such a lock will keep discardable segments from being discarded. Therefore, you'll probably want to limit your use of this technique to moveable segments.
In my next article, I'm going to discuss memory use by applications in Windows Version 3.0. I'll describe every available place for storing a byte of data and describe the impact of each on the system.
1For ease of reading, "Windows" refers to the Microsoft Windows graphical environment. "Windows" refers only to this Microsoft product and is not intended to refer to such products generally.
2As used herein, "DOS" refers to the MS-DOS and PC-DOS operating systems.
3As used herein, "OS/2" refers to the OS/2 operating system jointly developed by IBM and Microsoft.
Figure 1. Call GetWinFlags to determine the current operating mode.
DWORD dwFlags;
dwFlags = GetWinFlags ();
if (dwFlags & WF_PMODE)
{
if (dwFlags & WF_STANDARD)
{
/* STANDARD MODE */
}
else
{
/* ENHANCED MODE */
}
}
else
{
/* REAL MODE */
}
Figure 3. 80x86 Processor's Physical Address Space
Processor Address Lines Physical Address Space 8088 20 1Mb
8086 20 1Mb
80186 20 1Mb
80188 20 1Mb
80286 24 16Mb
80386SX 24 16Mb
80386 32 4Gb
i486 32 4Gb
Figure 4. Windows Memory Segment Attributes
Attribute Description Fixed Address of segment is fixed
Moveable Address of segment is not fixed, unless object has been locked
Discardable Segment can be purged from memory as needed
Figure 5. Four Types of Windows Memory Locks
Type of Lock Description Simple lock A segment is locked with a call to GlobalLock. This routine fixes a segment in place, and returns a far pointer to the data. Wired A segment is wired with a call to GlobalWire. When a segment must be fixed for a period of time, this routine first moves the segment to a lower part of memory before fixing a segment and returning a far pointer to the data. Fixed physical address A segment is fixed with a call to GlobalFix. In real mode, this is the same as a locked segment. In standard and 386 enhanced mode, this fixes a segment's physical address. Page-lock A segment is page-locked through a call to GlobalPageLock. In real mode and standard mode, this has the same effect as locking a segment. In enhanced mode, it prevents the virtual memory pages of a segment from being swapped to disk.