Get rid of -rndpg option for now, because none of the tests use it.
[pintos-anon] / doc / vm.texi
1 @node Project 3--Virtual Memory, Project 4--File Systems, Project 2--User Programs, Top
2 @chapter Project 3: Virtual Memory
3
4 By now you should be familiar with the inner workings of Pintos.  Your
5 OS can properly handle multiple threads of execution with proper
6 synchronization, and can load multiple user programs at once.  However,
7 the number and size of programs that can run is limited by the machine's
8 main memory size.  In this assignment, you will remove that limitation.
9
10 You will build this assignment on top of the last one.  It will benefit
11 you to get your project 2 in good working order before this assignment
12 so those bugs don't keep haunting you.  Test programs from the previous
13 project should also work with this project.
14
15 You will continue to handle Pintos disks and file systems the same way
16 you did in the previous assignment (@pxref{Using the File System}).
17
18 @menu
19 * Project 3 Background::        
20 * Project 3 Requirements::      
21 * Project 3 FAQ::               
22 @end menu
23
24 @node Project 3 Background
25 @section Background
26
27 @menu
28 * Project 3 Source Files::      
29 * Page Faults::                 
30 * Disk as Backing Store::       
31 * Memory Mapped Files Background::  
32 @end menu
33
34 @node Project 3 Source Files
35 @subsection Source Files
36
37 You will work in the @file{vm} directory for this project.  The
38 @file{vm} directory contains only @file{Makefile}s.  The only
39 change from @file{userprog} is that this new @file{Makefile} turns on
40 the setting @option{-DVM}.  All code you write will be in new
41 files or in files introduced in earlier projects.
42
43 You will probably be encountering just a few files for the first time:
44
45 @table @file
46 @item devices/disk.h
47 @itemx devices/disk.c
48 Provides access to the physical disk, abstracting away the rather awful
49 IDE interface.  You will use this interface to access the swap disk.
50 @end table
51
52 @menu
53 * Page Faults::
54 * Disk as Backing Store::
55 * Memory Mapped Files::
56 @end menu
57
58 @node Page Faults
59 @subsection Page Faults
60
61 For the last assignment, whenever a context switch occurred, the new
62 process installed its own page table into the machine.  The new page
63 table contained all the virtual-to-physical translations for the
64 process.  Whenever the processor needed to look up a translation, it
65 consulted the page table.  As long as the process only accessed
66 memory that it owned, all was well.  If the process accessed
67 memory it didn't own, it ``page faulted'' and @func{page_fault}
68 terminated the process.
69
70 When we implement virtual memory, the rules have to change.  A page
71 fault is no longer necessarily an error, since it might only indicate
72 that the page must be brought in from a disk file or from swap.  You
73 will have to implement a more sophisticated page fault handler to
74 handle these cases.
75
76 @menu
77 * Page Table Structure::        
78 * Working with Virtual Addresses::  
79 * Accessed and Dirty Bits::     
80 @end menu
81
82 @node Page Table Structure
83 @subsubsection Page Table Structure
84
85 On the 80@var{x}86, the page table format is fixed by hardware.  We
86 have provided code for managing page tables for you to use in
87 @file{userprog/pagedir.c}.  The functions in there provide an
88 abstract interface to all the page table functionality that you should need
89 to complete the project.  However, you may still find it worthwhile to
90 understand a little about the hardware page table format, so we'll go
91 into a little of detail about that in this section.
92
93 The top-level paging data structure is a page called the ``page
94 directory'' (PD) arranged as an array of 1,024 32-bit page directory
95 entries (PDEs), each of which represents 4 MB of virtual memory.  Each
96 PDE may point to the physical address of another page called a
97 ``page table'' (PT) arranged, similarly, as an array of 1,024
98 32-bit page table entries (PTEs), each of which translates a single 4
99 kB virtual page to a physical page.
100
101 Translation of a virtual address into a physical address follows
102 the three-step process illustrated in the diagram
103 below:@footnote{Actually, virtual to physical translation on the
104 80@var{x}86 architecture occurs via an intermediate ``linear
105 address,'' but Pintos (and most other 80@var{x}86 OSes) set up the CPU
106 so that linear and virtual addresses are one and the same.  Thus, you
107 can effectively ignore this CPU feature.}
108
109 @enumerate 1
110 @item
111 The most-significant 10 bits of the virtual address (bits 22@dots{}32)
112 index the page directory.  If the PDE is marked ``present,'' the
113 physical address of a page table is read from the PDE thus obtained.
114 If the PDE is marked ``not present'' then a page fault occurs.
115
116 @item
117 The next 10 bits of the virtual address (bits 12@dots{}21) index
118 the page table.  If the PTE is marked ``present,'' the physical
119 address of a data page is read from the PTE thus obtained.  If the PTE
120 is marked ``not present'' then a page fault occurs.
121
122 @item
123 The least-significant 12 bits of the virtual address (bits 0@dots{}11)
124 are added to the data page's physical base address, yielding the final
125 physical address.
126 @end enumerate
127
128 @example
129 @group
130  31                  22 21                  12 11                   0
131 +----------------------+----------------------+----------------------+
132 | Page Directory Index |   Page Table Index   |    Page Offset       |
133 +----------------------+----------------------+----------------------+
134              |                    |                     |
135      _______/             _______/                _____/
136     /                    /                       /
137    /    Page Directory  /      Page Table       /    Data Page
138   /     .____________. /     .____________.    /   .____________.
139   |1,023|____________| |1,023|____________|    |   |____________|
140   |1,022|____________| |1,022|____________|    |   |____________|
141   |1,021|____________| |1,021|____________|    \__\|____________|
142   |1,020|____________| |1,020|____________|       /|____________|
143   |     |            | |     |            |        |            |
144   |     |            | \____\|            |_       |            |
145   |     |      .     |      /|      .     | \      |      .     |
146   \____\|      .     |_      |      .     |  |     |      .     |
147        /|      .     | \     |      .     |  |     |      .     |
148         |      .     |  |    |      .     |  |     |      .     |
149         |            |  |    |            |  |     |            |
150         |____________|  |    |____________|  |     |____________|
151        4|____________|  |   4|____________|  |     |____________|
152        3|____________|  |   3|____________|  |     |____________|
153        2|____________|  |   2|____________|  |     |____________|
154        1|____________|  |   1|____________|  |     |____________|
155        0|____________|  \__\0|____________|  \____\|____________|
156                            /                      /
157 @end group
158 @end example
159
160 @node Working with Virtual Addresses
161 @subsubsection Working with Virtual Addresses
162
163 Header @file{threads/mmu.h} has useful functions for various
164 operations on virtual addresses.  You should look over the header
165 yourself.  The most important functions are described below.
166
167 @deftypefun uintptr_t pd_no (const void *@var{va})
168 Returns the page directory index for virtual address @var{va}.
169 @end deftypefun
170
171 @deftypefun uintptr_t pt_no (const void *@var{va})
172 Returns the page table index for virtual address @var{va}.
173 @end deftypefun
174
175 @deftypefun unsigned pg_ofs (const void *@var{va})
176 Returns the page offset of virtual address @var{va}.
177 @end deftypefun
178
179 @deftypefun {void *} pg_round_down (const void *@var{va})
180 Returns @var{va} rounded down to the nearest page boundary, that is,
181 @var{va} with its page offset set to 0.
182 @end deftypefun
183
184 @deftypefun {void *} pg_round_up (const void *@var{va})
185 Returns @var{va} rounded up to the nearest page boundary.
186 @end deftypefun
187
188 @node Accessed and Dirty Bits
189 @subsubsection Accessed and Dirty Bits
190
191 Most of the page table is under the control of the operating system, but
192 two bits in each page table entry are also manipulated by the CPU.  On
193 any read or write to the page referenced by a PTE, the CPU sets the
194 PTE's @dfn{accessed bit} to 1; on any write, the CPU sets the @dfn{dirty
195 bit} to 1.  The CPU never resets these bits to 0, but the OS may do so.
196
197 You will need to use the accessed and dirty bits in your submission to
198 choose which pages to evict from memory and to decide whether evicted
199 pages need to be written to disk.  The page table code in
200 @file{userprog/pagedir.c} provides functions for checking and setting
201 these bits.  These functions are described at the end of this section.
202
203 You need to watch out for @dfn{aliases}, that is, two (or more)
204 different virtual pages that refer to the same physical page frame.
205 When an aliased page is accessed, the accessed and dirty bits are
206 updated in only one page table entry (the one for the virtual address
207 used to access the page).  The accessed and dirty bits for the other
208 aliased virtual addresses are not updated.
209
210 In Pintos, every user virtual page is aliased to its kernel virtual
211 address.  You must manage these aliases somehow.  For example, your code
212 could check and update the accessed and dirty bits for both addresses.
213 Alternatively, the kernel could avoid the problem by only accessing user
214 data through the user virtual address.
215
216 @deftypefun bool pagedir_is_dirty (uint32_t *@var{pd}, const void *@var{vpage})
217 @deftypefunx bool pagedir_is_accessed (uint32_t *@var{pd}, const void *@var{vpage})
218 Returns true if page directory @var{pd} contains a page table entry for
219 virtual page @var{vpage} that is marked dirty (or accessed).  Otherwise,
220 returns false.
221 @end deftypefun
222
223 @deftypefun void pagedir_set_dirty (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
224 @deftypefunx void pagedir_set_accessed (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
225 If page directory @var{pd} has a page table entry for @var{vpage}, then
226 its dirty (or accessed) bit is set to @var{value}.
227 @end deftypefun
228
229 @node Disk as Backing Store
230 @subsection Disk as Backing Store
231
232 VM systems effectively use memory as a cache for disk.  From another
233 perspective, disk is a ``backing store'' for memory.  This provides the
234 abstraction of an (almost) unlimited virtual memory size.  You must
235 implement such a system, with the additional constraint that performance
236 should be close to that provided by physical memory.  You can use dirty
237 bits to tell whether pages need to be written back to disk when they're
238 evicted from main memory, and the accessed bits for page replacement
239 algorithms (@pxref{Accessed and Dirty Bits}).
240
241 As with any caching system, performance depends on the policy used to
242 decide what to keep in the cache and what to evict.  On a page fault,
243 the kernel must decide which page to replace.  Ideally, it will throw
244 out a page that will not be referenced for a long time, keeping in
245 memory those pages that are soon to be referenced.  Another
246 consideration is that if the replaced page has been modified, the page
247 must be first written to disk before the needed page can be brought in.
248 Many virtual memory systems avoid this extra overhead by writing
249 modified pages to disk in advance, so that later page faults can be
250 completed more quickly (but you do not have to implement this
251 optimization).
252
253 @node Memory Mapped Files Background
254 @subsection Memory Mapped Files
255
256 The file system is most commonly accessed with @code{read} and
257 @code{write} system calls.  A secondary interface is to ``map''
258 the file into the virtual address space.  The program can then use load
259 and store instructions directly on the file data.  An alternative view
260 is to see the file system is as ``durable memory'': files just store
261 data structures, so if you access ordinary data structures using normal
262 program instructions, why not access durable data structures the same
263 way?
264
265 Suppose file @file{foo} is @t{0x1000} bytes (4 kB, or one page) long.
266 If @file{foo} is mapped into memory starting at address @t{0x5000}, then
267 any memory accesses to locations @t{0x5000}@dots{}@t{0x5fff} will access
268 the corresponding bytes of @file{foo}.
269
270 A consequence of memory mapped files is that address spaces are
271 sparsely populated with lots of segments, one for each memory mapped
272 file (plus one each for code, data, and stack).
273
274 @node Project 3 Requirements
275 @section Requirements
276
277 This assignment is an open-ended design problem.  We are going to say as
278 little as possible about how to do things.  Instead we will focus on
279 what functionality we require your OS to support.  We will expect
280 you to come up with a design that makes sense.  You will have the
281 freedom to choose how to handle page faults, how to organize the swap
282 disk, how to implement paging, etc.
283
284 @menu
285 * Project 3 Design Document::   
286 * Page Table Management::       
287 * Paging To and From Disk::     
288 * Lazy Loading::                
289 * Stack Growth::                
290 * Memory Mapped Files::         
291 @end menu
292
293 @node Project 3 Design Document
294 @subsection Design Document
295
296 Before you turn in your project, you must copy @uref{vm.tmpl, , the
297 project 3 design document template} into your source tree under the name
298 @file{pintos/src/vm/DESIGNDOC} and fill it in.  We recommend that you
299 read the design document template before you start working on the
300 project.  @xref{Project Documentation}, for a sample design document
301 that goes along with a fictitious project.
302
303 @node Page Table Management
304 @subsection Page Table Management
305
306 Implement page directory and page table management to support virtual
307 memory.  You will need data structures to accomplish the following
308 tasks:
309
310 @itemize @bullet
311 @item
312 Some way of translating in software from virtual page frames to
313 physical page frames.  Consider using a hash table (@pxref{Hash
314 Table}).
315
316 It is possible to do this translation without adding a new data
317 structure, by modifying the code in @file{userprog/pagedir.c}.  However,
318 if you do that you'll need to carefully study and understand section 3.7
319 in @bibref{IA32-v3}, and in practice it is probably easier to add a new
320 data structure.
321
322 @item
323 Some way of finding a page on disk (in a file or in swap) if it is not
324 in memory.
325
326 You can generalize the virtual-to-physical page table, so that it allows
327 you to locate a page wherever it is in physical memory or on disk, or
328 you can make this a separate table.
329
330 @item
331 Some way of translating from physical page frames back to virtual page
332 frames, so that when you evict a physical page from its frame, you can
333 invalidate its page table entry (or entries).
334 @end itemize
335
336 The page fault handler, @func{page_fault} in
337 @file{threads/exception.c}, needs to do roughly the following:
338
339 @enumerate 1
340 @item
341 Locate the page backing the virtual
342 address that faulted.  It might be in the file system, in swap,
343 or it might be an invalid virtual address.
344 If you implement sharing, it might even
345 already be in physical memory, but not in the page table.
346
347 If the virtual address is invalid, that is, if there's nothing
348 assigned to go there, or if the virtual address is above
349 @code{PHYS_BASE}, meaning that it belongs to the kernel instead of the
350 user, then the process's memory access must be disallowed.  
351 In this case, terminate the process and free all of its resources.
352
353 @item
354 If the page is not in physical memory, fetch it by appropriate means.
355 If necessary to make room, first evict some other page from memory.
356 (When you do that you need to first remove references to the page from
357 any page table that refers to it.)
358
359 @item
360 Point the page table entry for the faulting virtual address to the
361 physical page.  You can use the functions in @file{userprog/pagedir.c}.
362 @end enumerate
363
364 You'll need to modify the ELF loader in @file{userprog/process.c} to
365 do page table management according to your new design.  As supplied,
366 it reads all the process's pages from disk and initializes the page
367 tables for them at the same time.  As a first step, you might
368 want to leave the code that reads the pages from disk, but
369 use your new page table management code to construct the page tables
370 only as page faults occur for them.
371
372 You should use the @func{palloc_get_page} function to get the page
373 frames that you use for storing user virtual pages.  Be sure to pass
374 the @code{PAL_USER} flag to this function when you do so, because that
375 allocates pages from a ``user pool'' separate from the ``kernel pool''
376 that other calls to @func{palloc_get_page} make (@pxref{Why PAL_USER?}).
377
378 You might find the Pintos bitmap code, in @file{lib/kernel/bitmap.c} and
379 @file{lib/kernel/bitmap.h}, useful for tracking pages.  A bitmap is an
380 array of bits, each of which can be true or false.  Bitmaps are
381 typically used to track usage in a set of (identical) resources: if
382 resource @var{n} is in use, then bit @var{n} of the bitmap is true.
383
384 There are many possible ways to implement virtual memory.  The above
385 is simply an outline of our suggested implementation.
386
387 @node Paging To and From Disk
388 @subsection Paging To and From Disk
389
390 Implement paging to and from files and the swap disk.  You may use the
391 disk on interface @code{hd1:1} as the swap disk, using the disk
392 interface prototyped in @code{devices/disk.h}.  From the @file{vm/build}
393 directory, use the command @code{pintos-mkdisk swap.dsk @var{n}} to
394 create an @var{n} MB swap disk named @file{swap.dsk}.  Afterward,
395 @file{swap.dsk} will automatically be attached as @code{hd1:1} when you run
396 @command{pintos}.  Alternatively, you can tell @command{pintos} to
397 use a temporary @var{n}-MB swap disk for a single run with
398 @option{--swap-disk=@var{n}}.
399
400 You will need routines to move a page from memory to disk and from
401 disk to memory, where ``disk'' is either a file or the swap disk.  If
402 you do a good job, your VM should still work when you
403 implement your own file system for the next assignment.
404
405 To fully handle page faults, you will need a way to track pages that
406 are used by a process but which are not in physical memory.  Pages in
407 swap should not be constrained to any particular ordering.  You will
408 also need a way to track physical page frames, to find an unused one
409 when needed, or to evict a page when memory is needed but no empty pages
410 are available.  The page table data structure that you designed should
411 do most of the work for you.
412
413 Implement a global page replacement algorithm.  You should be able to
414 use the ``accessed'' and ``dirty'' bits (@pxref{Accessed and Dirty
415 Bits}) to implement an approximation to LRU.  Your algorithm should
416 perform at least as well as the ``second chance'' or ``clock''
417 algorithm.
418
419 Your design should allow for parallelism.  Multiple processes should
420 be able to process page faults at once.  If one page fault require
421 I/O, in the meantime processes that do not fault should continue
422 executing and other page faults that do not require I/O should be able to
423 complete.  These criteria require some synchronization effort.
424
425 @node Lazy Loading
426 @subsection Lazy Loading
427
428 Since you will already be paging from disk, you should implement a
429 ``lazy'' loading scheme for new processes.  When a process is created,
430 it will not need all of its resources immediately, so it doesn't make
431 sense to load all its code, data, and stack into memory when the process
432 is created.  Instead, bring pages in from
433 the executable only as needed.  Use the
434 executable file itself as backing store for read-only segments, since
435 these segments won't change.  This means that read-only pages should not
436 be written to swap.
437
438 The core of the program loader is the loop in @func{load_segment} in
439 @file{userprog/process.c}.
440 Each time around the loop, @code{read_bytes} receives the number of
441 bytes to read from the executable file and @code{zero_bytes} receives
442 the number of bytes to initialize to zero following the bytes read.  The
443 two always sum to @code{PGSIZE} (4,096).  The handling of a page depends
444 on these variables' values:
445
446 @itemize @bullet
447 @item
448 If @code{read_bytes} equals @code{PGSIZE}, the page should be demand
449 paged from disk on its first access.
450
451 @item
452 If @code{zero_bytes} equals @code{PGSIZE}, the page does not need to
453 be read from disk at all because it is all zeroes.  You should handle
454 such pages by creating a new page consisting of all zeroes at the
455 first page fault.
456
457 @item
458 If neither @code{read_bytes} nor @code{zero_bytes} equals
459 @code{PGSIZE}, then part of the page is to be read from disk and the
460 remainder zeroed.  This is a special case.  You are allowed to handle
461 it by reading the partial page from disk at executable load time and
462 zeroing the rest of the page.  This is the only case in which we will
463 allow you to load a page in a non-``lazy'' fashion.  Many real OSes
464 such as Linux do not load partial pages lazily.
465 @end itemize
466
467 Incidentally, if you have trouble handling the third case above, you
468 can eliminate it temporarily by linking the test programs with a
469 special ``linker script.''  Read @file{Makefile.userprog} for
470 details.  We will not test your submission with this special linker
471 script, so the code you turn in must properly handle all cases.
472
473 @node Stack Growth
474 @subsection Stack Growth
475
476 Implement stack growth.  In project 2, the stack was a single page at
477 the top of the user virtual address space, and programs were limited to
478 that much stack.  Now, if the stack grows past its current size,
479 allocate additional page as necessary.
480
481 Allocate additional pages only if they ``appear'' to be stack accesses.
482 Devise a heuristic that attempts to distinguish stack accesses from
483 other accesses.  You can retrieve the user program's current stack
484 pointer from the @struct{intr_frame}'s @code{esp} member.
485
486 User programs are buggy if they write to the stack below the stack
487 pointer, because typical real OSes may interrupt a process at any time
488 to deliver a ``signal,'' which pushes data on the stack.@footnote{This rule is
489 common but not universal.  One modern exception is the
490 @uref{http://www.x86-64.org/documentation/abi.pdf, @var{x}86-64 System V
491 ABI}, which designates 128 bytes below the stack pointer as a ``red
492 zone'' that may not be modified by signal or interrupt handlers.}
493 However, the 80@var{x}86 @code{PUSH} instruction checks access
494 permissions before it adjusts the stack pointer, so it may cause a page
495 fault 4 bytes below the stack pointer.  (Otherwise, @code{PUSH} would
496 not be restartable in a straightforward fashion.)  Similarly, the
497 @code{PUSHA} instruction pushes 32 bytes at once, so it can fault 32
498 bytes below the stack pointer.
499
500 You may impose some absolute limit on stack size, as do most OSes.
501 (Some OSes make the limit user-adjustable, e.g.@: with the
502 @command{ulimit} command on many Unix systems.)
503
504 The first stack page need not be allocated lazily.  You can initialize
505 it with the command line arguments at load time, with no need to wait
506 for it to be faulted in.  (Even if you did wait, the very first
507 instruction in the user program is likely to be one that faults in the
508 page.)
509
510 @node Memory Mapped Files
511 @subsection Memory Mapped Files
512
513 Implement memory mapped files, including the following system calls.
514
515 @deftypefn {System Call} mapid_t mmap (int @var{fd}, void *@var{addr})
516 Maps the file open as @var{fd} into the process's virtual address
517 space.  The entire file is mapped into consecutive virtual pages
518 starting at @var{addr}.
519
520 If the file's length is not a multiple of @code{PGSIZE}, then some
521 bytes in the final mapped page ``stick out'' beyond the end of the
522 file.  Set these bytes to zero when the page is faulted in from disk,
523 and discard them when the page is written back to disk.
524
525 If successful, this function returns a ``mapping ID'' that
526 uniquely identifies the mapping within the process.  On failure,
527 it must return -1, which otherwise should not be a valid mapping id,
528 and the process's mappings must be unchanged.
529
530 A call to @code{mmap} may fail if the file open as @var{fd} has a
531 length of zero bytes.  It must fail if @var{addr} is not page-aligned
532 or if the range of pages mapped overlaps any existing set of mapped
533 pages, including the stack or pages mapped at executable load time.
534 It must also fail if @var{addr} is 0, because some Pintos code assumes
535 virtual page 0 is not mapped.  Finally, file descriptors 0 and 1,
536 representing console input and output, are not mappable.
537
538 Your VM system should use the @code{mmap}'d file itself as backing
539 store for the mapping.  That is, to evict a page mapped by
540 @code{mmap}, write it to the file it was mapped from.  (In fact, you
541 may choose to implement executable mappings as special, copy-on-write
542 file mappings.)
543 @end deftypefn
544
545 @deftypefn {System Call} void munmap (mapid_t @var{mapping})
546 Unmaps the mapping designated by @var{mapping}, which must be a
547 mapping ID returned by a previous call to @code{mmap} by the same
548 process that has not yet been unmapped.
549 @end deftypefn
550
551 All mappings are implicitly unmapped when a process exits, whether via
552 @code{exit} or by any other means.  When a mapping is unmapped, whether
553 implicitly or explicitly, all pages written to by the process are
554 written back to the file, and pages not written must not be.  The pages
555 are then removed from the process's list of virtual pages.
556
557 @node Project 3 FAQ
558 @section FAQ
559
560 @table @b
561 @item How much code will I need to write?
562
563 Here's a summary of our reference solution, produced by the
564 @command{diffstat} program.  The final row gives total lines inserted
565 and deleted; a changed line counts as both an insertion and a deletion.
566
567 This summary is relative to the Pintos base code, but we started from
568 the reference solution to project 2.  @xref{Project 2 FAQ}, for the
569 summary of project 2.
570
571 @verbatim
572  Makefile.build       |    4 
573  devices/timer.c      |   42 ++
574  threads/init.c       |    5 
575  threads/interrupt.c  |    2 
576  threads/thread.c     |   31 +
577  threads/thread.h     |   37 +-
578  userprog/exception.c |   12 
579  userprog/pagedir.c   |   10 
580  userprog/process.c   |  319 +++++++++++++-----
581  userprog/syscall.c   |  545 ++++++++++++++++++++++++++++++-
582  userprog/syscall.h   |    1 
583  vm/frame.c           |  162 +++++++++
584  vm/frame.h           |   23 +
585  vm/page.c            |  297 ++++++++++++++++
586  vm/page.h            |   50 ++
587  vm/swap.c            |   85 ++++
588  vm/swap.h            |   11 
589  17 files changed, 1532 insertions(+), 104 deletions(-)
590 @end verbatim
591
592 @item Do we need a working HW 2 to implement HW 3?
593
594 Yes.
595
596 @item How do I use the hash table provided in @file{lib/kernel/hash.c}?
597 @anchor{Hash Table}
598
599 First, you need to add a @struct{hash_elem} as a member of the
600 object that the hash table will contain.  Each @struct{hash_elem} allows
601 the object to a member of at most one hash table at a given time.  All
602 the hash table functions that deal with hash table items actually use
603 the address of a @struct{hash_elem}.  You can convert a pointer to a
604 @struct{hash_elem} member into a pointer to the structure in which
605 member is embedded using the @code{hash_entry} macro.
606
607 Second, you need to decide on a key type.  The key should be something
608 that is unique for each object, because a given hash table may not
609 contain two objects with equal keys.  Then you need to write two
610 functions.  The first is a @dfn{hash function} that converts a key
611 into an integer.  Some sample hash functions that you can use or just
612 examine are given in @file{lib/kernel/hash.c}.  The second needed
613 function is a @dfn{comparison function} that compares a pair of objects
614 and returns
615 true if the first is less than the second.  These two functions have
616 to be compatible with the prototypes for @code{hash_hash_func} and
617 @code{hash_less_func} in @file{lib/kernel/hash.h}.
618
619 Here's a quick example.  Suppose you want to put @struct{thread}s
620 in a hash table.  First, add a @struct{hash_elem} to the thread
621 structure by adding a line to its definition:
622
623 @example
624 struct hash_elem h_elem;     /* Hash table element. */
625 @end example
626
627 We'll choose the @code{tid} member in @struct{thread} as the key,
628 and write a hash function and a comparison function:
629
630 @example
631 /* Returns a hash for E. */
632 unsigned
633 thread_hash (const struct hash_elem *e, void *aux UNUSED)
634 @{
635   struct thread *t = hash_entry (e, struct thread, h_elem);
636   return hash_int (t->tid);
637 @}
638
639 /* Returns true if A's tid is less than B's tid. */
640 bool
641 thread_less (const struct hash_elem *a_,
642              const struct hash_elem *b_,
643              void *aux UNUSED)
644 @{
645   struct thread *a = hash_entry (a_, struct thread, h_elem);
646   struct thread *b = hash_entry (b_, struct thread, h_elem);
647   return a->tid < b->tid;
648 @}
649 @end example
650
651 Then we can create a hash table like this:
652
653 @example
654 struct hash threads;
655
656 hash_init (&threads, thread_hash, thread_less, NULL);
657 @end example
658
659 Finally, if @code{@var{t}} is a pointer to a @struct{thread},
660 then we can insert it into the hash table with:
661
662 @example
663 hash_insert (&threads, &@var{t}->h_elem);
664 @end example
665
666 The CS109 and CS161 textbooks have chapters on hash tables.
667
668 @item Why do the hash table functions have @var{aux} parameters?
669
670 In simple cases you won't have any need for the @var{aux} parameters.
671 In these cases you can just pass a null pointer to @func{hash_init}
672 for @var{aux} and ignore the values passed to the hash function and
673 comparison functions.  (You'll get a compiler warning if you don't use
674 the @var{aux} parameter, but you can turn that off with the
675 @code{UNUSED} macro, as shown above, or you can just ignore it.)
676
677 @var{aux} is useful when you have some property of the data in the
678 hash table that's both constant and needed for hashing or comparisons,
679 but which is not stored in the data items themselves.  For example, if
680 the items in a hash table contain fixed-length strings, but the items
681 themselves don't indicate what that fixed length is, you could pass
682 the length as an @var{aux} parameter.
683
684 @item Can we change the hash table implementation?
685
686 You are welcome to modify it.  It is not used by any of the code we
687 provided, so modifying it won't affect any code but yours.  Do
688 whatever it takes to make it work the way you want.
689
690 @item What extra credit is available?
691
692 You may implement sharing: when multiple processes are created that use
693 the same executable file, share read-only pages among those processes
694 instead of creating separate copies of read-only segments for each
695 process.  If you carefully designed your page table data structures,
696 sharing of read-only pages should not make this part significantly
697 harder.
698
699 @end table
700
701 @menu
702 * Page Table and Paging FAQ::   
703 * Memory Mapped File FAQ::      
704 @end menu
705
706 @node Page Table and Paging FAQ
707 @subsection Page Table and Paging FAQ
708
709 @table @b
710 @item Does the virtual memory system need to support data segment growth?
711
712 No.  The size of the data segment is determined by the linker.  We still
713 have no dynamic allocation in Pintos (although it is possible to
714 ``fake'' it at the user level by using memory-mapped files).  Supporting
715 data segment growth should add little additional complexity to a
716 well-designed system.
717
718 @item Why should I use @code{PAL_USER} for allocating page frames?
719 @anchor{Why PAL_USER?}
720
721 Passing @code{PAL_USER} to @func{palloc_get_page} causes it to allocate
722 memory from the user pool, instead of the main kernel pool.  Running out
723 of pages in the user pool just causes user programs to page, but running
724 out of pages in the kernel pool will cause many failures because so many
725 kernel functions need to obtain memory.
726 You can layer some other allocator on top of @func{palloc_get_page} if
727 you like, but it should be the underlying mechanism.
728
729 Also, you can use the @option{-u} option to @command{pintos} to limit
730 the size of the user pool, which makes it easy to test your VM
731 implementation with various user memory sizes.
732 @end table
733
734 @node Memory Mapped File FAQ
735 @subsection Memory Mapped File FAQ
736
737 @table @b
738 @item How do we interact with memory-mapped files?
739
740 Let's say you want to map a file called @file{foo} into your address
741 space at address @t{0x10000000}. You open the file then use @code{mmap}:
742
743 @example
744 #include <stdio.h>
745 #include <syscall.h>
746
747 int main (void)
748 @{
749     void *addr = (void *) 0x10000000;
750     int fd = open ("foo");
751     mapid_t map = mmap (fd, addr);
752     if (map != -1)
753         printf ("success!\n");
754 @}
755 @end example
756
757 Suppose @file{foo} is a text file and you want to print the first 64
758 bytes on the screen (assuming, of course, that the length of the file
759 is at least 64).  Without @code{mmap}, you'd need to allocate a
760 buffer, use @code{read} to get the data from the file into the buffer,
761 and finally use @code{write} to put the buffer out to the display. But
762 with the file mapped into your address space, you can directly address
763 it like so:
764
765 @example
766 write (addr, 64, STDOUT_FILENO);
767 @end example
768
769 Similarly, if you wanted to replace the first byte of the file,
770 all you need to do is:
771
772 @example
773 addr[0] = 'b';
774 @end example
775
776 When you're done using the memory-mapped file, you simply unmap
777 it:
778
779 @example
780 munmap (map);
781 @end example
782
783 The @command{mcp} program in @file{src/examples} shows how to copy a
784 file using memory-mapped I/O.
785
786 @item What if two processes map the same file into memory?
787
788 There is no requirement in Pintos that the two processes see
789 consistent data.  Unix handles this by making the two mappings share the
790 same physical page, but the @code{mmap} system call also has an
791 argument allowing the client to specify whether the page is shared or
792 private (i.e.@: copy-on-write).
793
794 @item What happens if a user removes a @code{mmap}'d file?
795
796 The mapping should remain valid, following the Unix convention.
797 @xref{Removing an Open File}, for more information.
798
799 @item If a user closes a mapped file, should it be automatically unmapped?
800
801 No.  Once created the mapping is valid until @code{munmap} is called
802 or the process exits.
803 @end table