Move problem 1-2 (join) into project 2 as the "wait" system call.
[pintos-anon] / doc / userprog.texi
index e3771e4e1aaf0f79e089841fa9d6432903737973..9fe874d5735b6115a136e32ddda990cf49a87d94 100644 (file)
@@ -14,10 +14,8 @@ assignment.  However, you will also be interacting with almost every
 other part of the code for this assignment. We will describe the
 relevant parts below. If you are confident in your HW1 code, you can
 build on top of it.  However, if you wish you can start with a fresh
-copy of the code and re-implement @func{thread_join}, which is the
-only part of project #1 required for this assignment.  Your submission
-should define @code{THREAD_JOIN_IMPLEMENTED} in @file{constants.h}
-(@pxref{Conditional Compilation}).
+copy of the code.  No code from project 1 is required for this
+assignment.
 
 Up to now, all of the code you have written for Pintos has been part
 of the operating system kernel.  This means, for example, that all the
@@ -40,7 +38,7 @@ working with, you should probably undo the test cases from project 1.
 * Using the File System::       
 * How User Programs Work::      
 * Virtual Memory Layout::       
-* Global Requirements::         
+* Grading Requirements::        
 * Problem 2-1 Argument Passing::  
 * Problem 2-2 System Calls::    
 * User Programs FAQ::           
@@ -280,8 +278,8 @@ that needs @var{N} pages of memory must not require that all @var{N}
 be contiguous.  In fact, it must not require that any of the pages be
 contiguous.
 
-@node Global Requirements
-@section Global Requirements
+@node Grading Requirements
+@section Grading Requirements
 
 For testing and grading purposes, we have some simple overall
 requirements:
@@ -328,6 +326,16 @@ make sure that it takes the start-up process name and arguments from
 the @samp{-ex} argument.  For example, running @code{pintos run -ex
 "testprogram 1 2 3 4"} will spawn @samp{testprogram 1 2 3 4} as the
 first process.
+
+@item
+In the previous project, we required that you provided some specific
+function interfaces, because we tested your project by compiling our
+test code into it.  For this project and all later projects, this is
+no longer necessary, because we will do all of our testing with user
+programs.  You must make sure that the user program interface meets
+the specifications described in the assignments, but given that
+constraint you are free to restructure or rewrite kernel code however
+you wish.
 @end itemize
 
 @node Problem 2-1 Argument Passing
@@ -397,7 +405,7 @@ etc.
 @item SYS_exit
 @itemx void exit (int @var{status})
 Terminates the current user program, returning @var{status} to the
-kernel.  If the process's parent @func{join}s it, this is the status
+kernel.  If the process's parent @func{wait}s for it, this is the status
 that will be returned.  Conventionally, a @var{status} of 0 indicates
 a successful exit.  Other values may be used to indicate user-defined
 conditions (usually errors).
@@ -405,18 +413,40 @@ conditions (usually errors).
 @item SYS_exec
 @itemx pid_t exec (const char *@var{cmd_line})
 Runs the executable whose name is given in @var{cmd_line}, passing any
-given arguments, and returns the new process's program id (pid).  If
-there is an error loading this program, may return pid -1, which
-otherwise should not be a valid id number.
-
-@item SYS_join
-@itemx int join (pid_t @var{pid})
-Joins the process @var{pid}, using the join rules from the last
-assignment, and returns the process's exit status.  If the process was
-terminated by the kernel (i.e.@: killed due to an exception), the exit
-status should be -1.  If the process was not a child of the calling
-process, the return value is undefined (but kernel operation must not
-be disrupted).
+given arguments, and returns the new process's program id (pid).  Must
+return pid -1, which otherwise should not be a valid program id, if
+there is an error loading this program.
+
+@item SYS_wait
+@itemx int wait (pid_t @var{pid})
+Waits for process @var{pid} to die and returns its exit status.  If it
+was terminated by the kernel (i.e.@: killed due to an exception),
+returns -1.  If @var{pid} is invalid or if it was not a child of the
+calling thread, or if @code{wait} has already been successfully
+called for the given @var{pid}, returns -1 immediately, without
+waiting.
+
+You must ensure that Pintos does not terminate until the initial
+process exits.  The supplied Pintos code tries to do this by calling
+@func{process_wait} (in @file{userprog/process.c}) from @func{main}
+(in @file{threads/init.c}).  We suggest that you implement
+@func{process_wait} according to the comment at the top of the
+function and then implement the @code{wait} system call in terms of
+@func{process_wait}.
+
+All of a process's resources, including its @struct{thread}, must be
+freed whether its parent ever waits for it or not, and regardless of
+whether the child exits before or after its parent.
+
+Children are not inherited, that is, if @var{A} has child @var{B} and
+@var{B} has child @var{C}, then @var{A} always returns immediately
+should it try to wait for @var{C}, even if @var{B} is dead.
+
+Consider all the ways a wait can occur: nested waits (@var{A} waits
+for @var{B}, then @var{B} waits for @var{C}), multiple waits (@var{A}
+waits for @var{B}, then @var{A} waits for @var{C}), and so on.  Does
+your @func{wait} work if it is called on a process that has not yet
+been scheduled for the first time?
 
 @item SYS_create
 @itemx bool create (const char *@var{file}, unsigned @var{initial_size})
@@ -516,9 +546,9 @@ recommend against modifying code in the @file{filesys} directory.}
 
 We have provided you a user-level function for each system call in
 @file{lib/user/syscall.c}.  These provide a way for user processes to
-invoke each system call from a C program.  Each of them calls an
-assembly language routine in @file{lib/user/syscall-stub.S}, which in
-turn invokes the system call interrupt and returns.
+invoke each system call from a C program.  Each uses a little inline
+assembly code to invoke the system call and (if appropriate) returns the
+system call's return value.
 
 When you're done with this part, and forevermore, Pintos should be
 bulletproof.  Nothing that a user program can do should ever cause the
@@ -541,9 +571,7 @@ value), returning an undefined value, or terminating the process.
 @item
 @b{Do we need a working project 1 to implement project 2?}
 
-You may find the code for @func{thread_join} to be useful in
-implementing the join syscall, but besides that, you can use
-the original code provided for project 1.
+No.
 
 @item
 @b{@samp{pintos put} always panics.}
@@ -635,7 +663,7 @@ process running in it (if created with @func{process_execute}) or not
 in the kernel.
 
 A @code{pid_t} identifies a user process.  It is used by user
-processes and the kernel in the @code{exec} and @code{join} system
+processes and the kernel in the @code{exec} and @code{wait} system
 calls.
 
 You can choose whatever suitable types you like for @code{tid_t} and
@@ -686,7 +714,7 @@ provide a little bit of helpful code:
    Returns true if successful, false if USRC is invalid. */
 static inline bool get_user (uint8_t *dst, const uint8_t *usrc) {
   int eax;
-  asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:"
+  asm ("mov %%eax, offset 1f; mov %%al, %2; mov %0, %%al; 1:"
        : "=m" (*dst), "=&a" (eax) : "m" (*usrc));
   return eax != 0;
 }
@@ -695,7 +723,7 @@ static inline bool get_user (uint8_t *dst, const uint8_t *usrc) {
    Returns true if successful, false if UDST is invalid. */
 static inline bool put_user (uint8_t *udst, uint8_t byte) {
   int eax;
-  asm ("movl $1f, %%eax; movb %b2, %0; 1:"
+  asm ("mov %%eax, offset 1f; mov %0, %b2; 1:"
        : "=m" (*udst), "=&a" (eax) : "r" (byte));
   return eax != 0;
 }