Make mmap use segment IDs.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 5 Mar 2005 07:33:56 +0000 (07:33 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 5 Mar 2005 07:33:56 +0000 (07:33 +0000)
TODO
doc/vm.texi
src/lib/user/syscall.h

diff --git a/TODO b/TODO
index 711a4ef3264763f060ab48f6ba2b4eac1e1d4528..1999f7033692229667ea30bb5df30aab22620b1b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,6 +4,9 @@
 
 * We need better example programs.
 
+  - Need an mmap example program as a replacement for the crappy mmap FAQ
+    question.
+
 * Threads:
 
   - join-invalid doesn't compile if tid_t is not scalar type.
     Alternately we could just remove the synchronization on pid
     selection and check that students fix it.
 
+* VM project:
+
+  - Discuss the perils of mixing dirty bits between kernel and user virtual
+    memory.
+
+  - Sample solution.
+
 * Filesys project:
 
   - Increase maximum disk size from 8 MB to something that actually
@@ -50,6 +60,8 @@
 
   - Get rid of "dump" commands--they're not really useful.
 
+  - Sample solution.
+
 * Documentation:
 
   - Finish writing tour.
 
     . Low-level x86 stuff, like paged page tables.
 
-    . Other good ideas.
+    . Specifics on how to implement sbrk, malloc.
 
-  - mmap/munmap should use segment IDs like Nachos.  Too hard
-    otherwise.
+    . Other good ideas.
 
   - Add src/testcases/vm, src/testcases/filesys and make it clear to use
     them?
index 6eff4925c262759137396831a46dbde7bb462d4b..37769f9acc1cf7192fbeed337a886e860449f6e7 100644 (file)
@@ -269,9 +269,14 @@ The user program's current stack pointer is in the @struct{intr_frame}'s
 @code{esp} member.
 
 @item
-Only buggy user programs write to memory within the stack but below the
-stack pointer.  This is because more advanced OSes may interrupt a
-process at any time to deliver a ``signal'' and this uses the stack.
+Only buggy 80@var{x}86 user programs write to memory within the
+stack but below the stack pointer.  This is because more advanced OSes
+may interrupt a process at any time to deliver a ``signal'' and this
+uses the stack.@footnote{This rule is common but not universal.  One
+modern exception is the
+@uref{http://www.x86-64.org/documentation/abi.pdf, @var{x}86-64 System
+V ABI}, which designates 128 bytes below the stack pointer as a ``red
+zone'' that may not be modified by signal or interrupt handlers.}
 
 @item
 The 80@var{x}86 @code{push} instruction may cause a page fault 4 bytes
@@ -475,77 +480,42 @@ You will need to implement the following system calls:
 
 @table @code
 @item SYS_mmap
-@itemx bool mmap (int @var{fd}, void *@var{addr}, unsigned @var{length})
+@itemx mapid_t mmap (int @var{fd}, void *@var{addr})
 
-Maps the file open as @var{fd} into the process's address space
-starting at @var{addr} for @var{length} bytes.  Returns true if
-successful, false on failure.  Failure cases include the following:
+Maps the file open as @var{fd} into the process's virtual address
+space.  The entire file is mapped into consecutive virtual pages
+starting at @var{addr}.
 
-@itemize @bullet
-@item
-@var{addr} is not page-aligned.
-
-@item
-@var{length} is not positive.
-
-@item
-The range of pages mapped overlaps any existing set of mapped pages,
-including the stack or pages mapped at executable load time.
-@end itemize
-
-@var{length} is treated as if it were rounded up to the nearest
-multiple of the page size, that is, as if the first statement in the
-system call's implementation were
-@example
-length = ROUND_UP (length, PGSIZE);
-@end example
-(The @code{ROUND_UP} macro is defined in @file{<round.h>}.)
-The remainder of this description assumes that this has been done.
-
-If @var{length} is less than @var{fd}'s length, you should only map
-the first @var{length} bytes of the file.  If @var{length} is greater
-than @var{fd}'s length, when the file's length is also rounded up to a
-page multiple, the call should fail.  Ideally it would extend the
-file, but our file system does not yet support growing files.
-
-If @var{length} is greater than @var{fd}'s (unrounded) length, then some
+If the file's length is not a multiple of @code{PGSIZE}, then some
 bytes in the final mapped page ``stick out'' beyond the end of the
-file.  Set these bytes to zero when the page is faulted in from
-disk, and discard them when the page is written back to disk.
+file.  Set these bytes to zero when the page is faulted in from disk,
+and discard them when the page is written back to disk.
 
-Your VM system should use the @code{mmap}'d file itself as
-backing store for the mapped segment.  That is, to evict a page mapped by
-@code{mmap} must be evicted, write it to the file it was mapped from.
-(In fact, you may choose to implement executable mappings as a special
-case of file mappings.)
+If successful, this function returns a ``mapping ID'' that must
+uniquely identify the mapping within the given process.  On failure,
+it must return -1, which otherwise should not be a valid mapping id.
 
-@item SYS_munmap
-@itemx bool munmap (void *addr, unsigned length)
+A call to @code{mmap} may fail if the file open as @var{fd} has a
+length of zero bytes.  It must fail if @var{addr} is not page-aligned
+or if the range of pages mapped overlaps any existing set of mapped
+pages, including the stack or pages mapped at executable load time.
 
-Unmaps @var{length} bytes starting at @var{addr}.  Returns true on
-success, false on failure.  Failure cases include the following:
+Your VM system should use the @code{mmap}'d file itself as backing
+store for the mapping.  That is, to evict a page mapped by
+@code{mmap}, write it to the file it was mapped from.  (In fact, you
+may choose to implement executable mappings as a special case of file
+mappings.)
 
-@itemize @bullet
-@item
-@var{addr} is not page-aligned.
-
-@item
-@var{length} is not positive.
-
-@item
-One or more pages within the range to be unmapped were not mapped
-using the @code{mmap} system call.
-@end itemize
-
-As with @code{mmap}, @var{length} is treated as if it were rounded up
-to the nearest multiple of the page size.
+@item SYS_munmap
+@itemx bool munmap (mapid_t @var{mapping})
 
-It is valid to unmap only some of the pages that were mapped in a
-previous system call.
+Unmaps the mapping designated by @var{mapping}, which must be a
+mapping ID returned by a previous call to @code{mmap} by the same
+process that has not yet been unmapped.
 @end table
 
 All mappings are implicitly unmapped when a process exits, whether via
-@code{exit} or by any other means.  When a file is unmapped, whether
+@code{exit} or by any other means.  When a mapping is unmapped, whether
 implicitly or explicitly, all outstanding changes are written to the
 file, and the pages are removed from the process's list of used
 virtual pages.
@@ -710,8 +680,7 @@ various user memory sizes.
 @b{How do we interact with memory-mapped files?}
 
 Let's say you want to map a file called @file{foo} into your address
-space at address @t{0x10000000}. You open the file, determine its
-length, and then use @code{mmap}:
+space at address @t{0x10000000}. You open the file then use @code{mmap}:
 
 @example
 #include <stdio.h>
@@ -721,8 +690,8 @@ int main (void)
 @{
     void *addr = (void *) 0x10000000;
     int fd = open ("foo");
-    int length = filesize (fd);
-    if (mmap (fd, addr, length))
+    mapid_t map = mmap (fd, addr);
+    if (map != -1)
         printf ("success!\n");
 @}
 @end example
@@ -750,14 +719,14 @@ When you're done using the memory-mapped file, you simply unmap
 it:
 
 @example
-munmap (addr, length);
+munmap (map);
 @end example
 
 @item
-@b{What if two processes memory-map the same file?}
+@b{What if two processes map the same file into memory?}
 
 There is no requirement in Pintos that the two processes see
-consistent data.  Unix handles this by making the processes share the
+consistent data.  Unix handles this by making the two mappings share the
 same physical page, but the @code{mmap} system call also has an
 argument allowing the client to specify whether the page is shared or
 private (i.e.@: copy-on-write).
@@ -765,18 +734,18 @@ private (i.e.@: copy-on-write).
 @item
 @b{What happens if a user removes a @code{mmap}'d file?}
 
-You should follow the Unix convention and the mapping should still be
-valid.  @xref{Removing an Open File}, for more information.
+The mapping should remain valid, following the Unix convention.
+@xref{Removing an Open File}, for more information.
 
 @item
 @b{What if a process writes to a page that is memory-mapped, but the
 location written to in the memory-mapped page is past the end
 of the memory-mapped file?}
 
-Can't happen.  @code{mmap} checks that the mapped region is within the
-file's length and Pintos provides no way to shorten a file.  (Until
-project 4, there's no way to extend a file either.)  You can remove a
-file, but the mapping remains valid (see the previous question).
+Can't happen.  @code{mmap} maps an entire file and Pintos provides no
+way to shorten a file.  (Until project 4, there's no way to extend a
+file either.)  You can remove a file, but the mapping remains valid
+(see the previous question).
 
 @item
 @b{Do we have to handle memory mapping @code{stdin} or @code{stdout}?}
@@ -786,18 +755,10 @@ can seek to any location in the file.  Since the console device has
 neither of these properties, @code{mmap} should return false when the
 user attempts to memory map a file descriptor for the console device.
 
-@item
-@b{What happens when a process exits with mapped files?}
-
-When a process finishes, each of its mapped files is implicitly
-unmapped.  When a process @code{mmap}s a file and then writes into the
-area for the file it is making the assumption the changes will be
-written to the file.
-
 @item
 @b{If a user closes a mapped file, should it be automatically
 unmapped?}
 
-No, once created the mapping is valid until @code{munmap} is called
+No.  Once created the mapping is valid until @code{munmap} is called
 or the process exits.
 @end enumerate
index 188576d35edbe205507fa2d61e6dc4644014be87..f6294667428490acd3debb417c7c369981ca7a17 100644 (file)
@@ -7,6 +7,9 @@
 typedef int pid_t;
 #define PID_ERROR ((pid_t) -1)
 
+typedef int mapid_t;
+#define MAPID_ERROR ((mapid_t) -1)
+
 void halt (void) NO_RETURN;
 void exit (int status) NO_RETURN;
 pid_t exec (const char *file);
@@ -20,8 +23,8 @@ int write (int fd, const void *buffer, unsigned length);
 void seek (int fd, unsigned position);
 unsigned tell (int fd);
 void close (int fd);
-bool mmap (int fd, void *addr, unsigned length);
-bool munmap (void *addr, unsigned length);
+mapid_t mmap (int fd, void *addr);
+bool munmap (mapid_t);
 bool chdir (const char *dir);
 bool mkdir (const char *dir);
 void lsdir (void);