[CS Dept logo]

Com Sci 230

Homeworks for Spring 1998

Nachos Project #4: Due Friday 29 May 1998
Demand Paged Virtual Memory

Copyright information

Last modified: Fri May 15 13:19:30 CDT


Project #4 is due on Friday, 29 May, at 7:30 AM. Use the submit-project Project_4 command to hand in your work as you did in previous project steps. As before, submit partial results, but make each submission self-contained and complete in terms of demonstration and explanation.

Basic goals

In this project, you implement virtual memory with demand paging.

General requirements

The good old general requirements still apply.

Special requirements and comments for this assignment

The project tasks

  1. Modify your Nachos OS to use the TLB instead of hardware interpretation of page tables. For a start, you should leave the page tables as they are, but add code to the PageFault exception in ExceptionHandler to do translation through the page table whenever there is a TLB miss. You must also add code to maintain the contents of the TLB. On each context switch, you need to clear the TLB by marking all entries invalid. When there is a PageFault exception, you need to add an entry to the TLB containing the missing page (which, for now, is guaranteed to be in main memory), throwing out an old entry if the TLB was already full, and re-executing the instruction causing the fault (do this by returning from ExceptionHandler without incrementing the PC). It is OK to throw out a randomly chosen TLB entry. You may implement a cleverer replacement strategy if you like, but I will give extra credit only if you present a sensible reason to hope that it really improves things.


  2. Replace the normal page tables with a single inverted page table, mapping physical page frames in main memory to virtual page numbers. Now, address translation must search for the appropriate physical page frame. Make the search fast and simple with a trivial hashing function: map the virtual page number p to the page frame numbered p mod s, where s is the size of main memory measured in page frames. Use chaining or open addressing to search when more than one virtual page number gets mapped to the same page frame. Notice that the inverted page table needs to keep track of the address space owning a given frame, as well as the virtual page number in that address space. You might as well incorporate the "dirty" and "use" bits as well, although you won't need them until the next task. You may decide to add other information to this table as your work progresses. Notice that some information in the inverted page table repeats information in the TLB. You must keep the two consistent at appropriate times.


  3. Now, implement virtual memory with demand paging. For each address space, create a swap file containing the entire contents of the address space. Copy in the executable file, and initialize all other contents to 0. Whenever a page is addressed that is not in main memory, load it into an appropriate page frame. Notice that virtual addresses are the same as physical addresses in the swap file. If main memory is full, remove any page frame that you like, and write it to the appropriate swap file. I will give a modest amount of extra credit, for a good immplementation of the clock algorithm or some other sensible method for choosing a page to swap out. Please don't spend time on replacement algorithms until you've solved all of the basic problems really well.

    Even though the current implementation of the file system is synchronous, you should assume that while a given thread is paging, many other threads can run. Make sure that there are no problems resulting from many interleaved accesses to virtual memory. Create test cases that yield the CPU just before and after access to files. There are three main problems to watch out for:

    1. A page frame could disappear before it can be accessed. It may be sufficient just to make this highly unlikely, rather than impossible.
    2. Worse, a page frame could be reallocated before the read from disk completes, leading to an inconsistency between the memory map and the actual contents of memory.
    3. A page might be fetched from disk just before it gets updated by writeback from main memory. This is the cache coherence problem, applied to main memory as a disk cache.
    You need some careful application of synchronization tools to avoid these sorts of problem.



  4. (Com Sci 330 only).

    Implement sparse virtual address spaces. Associate with each space a segment table mapping virtual addresses to addresses in the swap file. Allocate space in the swap file only for pages that are actually written. This means that the code for the PageFault exception must allocate swap space when necessary, and update the swap-segment table. Take sensible steps to avoid unnecessary file operations, such as reading and writing uninitialized pages full of 0s. If you do this right, there is no need to consult the segment table when a page is actually in main memory.

    Now, avoid moving the executable file for a user thread by mapping it onto a segment of virtual memory. You now need to keep track in the segment table of which file is associated with each segment.

Don't do this, but take a look

Here's what the Com Sci 330 assignment is aiming towards. You don't need to do it, but I couldn't bear to throw it away. Mapping the executable file exercises most of the structure of a general segment-to-file map, but cuts the total coding a bit. Think about even more flexible manipulations of virtual memory. One intriguing idea is to build the whole file system on top of virtual memory, rather than using files to implement VM. That is, the VM code works directly with the DISK to implement segementation and demand paging. Then, a file is defined to be a certain segment of virtual pages.

Good advice

See the Nachos Road Map section on experience with virtual memory for some useful ideas. Watch out, though: the assignment used at Duke is quite different from ours.