Get rid of unnecessary barrier. Improve comment.
[pintos-anon] / src / userprog / process.c
index 88c9d8dcae20995bb5e7dc3b4b2d5a42ca5b8e6e..31629c7b594717689115e190e98286bdac3b15c4 100644 (file)
@@ -21,8 +21,9 @@ static thread_func execute_thread NO_RETURN;
 static bool load (const char *cmdline, void (**eip) (void), void **esp);
 
 /* Starts a new thread running a user program loaded from
-   FILENAME.  The new thread may be scheduled before
-   process_execute() returns.*/
+   FILENAME.  The new thread may be scheduled (and may even exit)
+   before process_execute() returns.  Returns the new process's
+   thread id, or TID_ERROR if the thread cannot be created. */
 tid_t
 process_execute (const char *filename) 
 {
@@ -54,13 +55,9 @@ execute_thread (void *filename_)
 
   /* Initialize interrupt frame and load executable. */
   memset (&if_, 0, sizeof if_);
-  if_.gs = SEL_UDSEG;
-  if_.fs = SEL_UDSEG;
-  if_.es = SEL_UDSEG;
-  if_.ds = SEL_UDSEG;
+  if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
   if_.cs = SEL_UCSEG;
   if_.eflags = FLAG_IF | FLAG_MBS;
-  if_.ss = SEL_UDSEG;
   success = load (filename, &if_.eip, &if_.esp);
 
   /* If load failed, quit. */
@@ -68,9 +65,6 @@ execute_thread (void *filename_)
   if (!success) 
     thread_exit ();
 
-  /* Switch page tables. */
-  process_activate ();
-
   /* Start the user process by simulating a return from an
      interrupt, implemented by intr_exit (in
      threads/intr-stubs.S).  Because intr_exit takes all of its
@@ -81,6 +75,21 @@ execute_thread (void *filename_)
   NOT_REACHED ();
 }
 
+/* Waits for thread TID to die and returns its exit status.  If
+   it was terminated by the kernel (i.e. killed due to an
+   exception), returns -1.  If TID is invalid or if it was not a
+   child of the calling process, or if process_wait() has already
+   been successfully called for the given TID, returns -1
+   immediately, without waiting.
+
+   This function will be implemented in problem 2-2.  For now, it
+   does nothing. */
+int
+process_wait (tid_t child_tid UNUSED) 
+{
+  return -1;
+}
+
 /* Free the current process's resources. */
 void
 process_exit (void)
@@ -89,13 +98,16 @@ process_exit (void)
   uint32_t *pd;
 
   /* Destroy the current process's page directory and switch back
-     to the kernel-only page directory.  We have to set
-     cur->pagedir to NULL before switching page directories, or a
-     timer interrupt might switch back to the process page
-     directory. */
+     to the kernel-only page directory. */
   pd = cur->pagedir;
   if (pd != NULL) 
     {
+      /* We must set cur->pagedir to NULL before switching page
+         directories, so that a timer interrupt can't switch back
+         to the process page directory.  We must activate the
+         base page directory before destroying the process's page
+         directory, or our active page directory will be one
+         that's been freed (and cleared). */
       cur->pagedir = NULL;
       pagedir_activate (NULL);
       pagedir_destroy (pd);
@@ -184,12 +196,12 @@ static bool load_segment (struct file *, const struct Elf32_Phdr *);
 static bool setup_stack (void **esp);
 
 /* Aborts loading an executable, with an error message. */
-#define LOAD_ERROR(MSG)                                         \
-        do {                                                    \
-                printf ("load: %s: ", filename);      \
-                printf MSG;                                     \
-                printf ("\n");                                  \
-                goto done;                                     \
+#define LOAD_ERROR(MSG)                                 \
+        do {                                            \
+                printf ("load: %s: ", filename);        \
+                printf MSG;                             \
+                printf ("\n");                          \
+                goto done;                              \
         } while (0)
 
 /* Loads an ELF executable from FILENAME into the current thread.
@@ -206,10 +218,11 @@ load (const char *filename, void (**eip) (void), void **esp)
   bool success = false;
   int i;
 
-  /* Allocate page directory. */
+  /* Allocate and activate page directory. */
   t->pagedir = pagedir_create ();
   if (t->pagedir == NULL)
     LOAD_ERROR (("page directory allocation failed"));
+  process_activate ();
 
   /* Open executable file. */
   file = filesys_open (filename);
@@ -337,10 +350,10 @@ load_segment (struct file *file, const struct Elf32_Phdr *phdr)
   /* Validate virtual memory region to be mapped.
      The region must both start and end within the user address
      space range starting at 0 and ending at PHYS_BASE (typically
-     3 GB == 0xc0000000). */
+     3 GB == 0xc0000000).  We don't allow mapping page 0 .*/
   start = pg_round_down ((void *) phdr->p_vaddr);
   end = pg_round_up ((void *) (phdr->p_vaddr + phdr->p_memsz));
-  if (start >= PHYS_BASE || end >= PHYS_BASE || end < start) 
+  if (start == 0 || start >= PHYS_BASE || end >= PHYS_BASE || end < start) 
     {
       printf ("bad virtual region %08lx...%08lx\n",
               (unsigned long) start, (unsigned long) end);