Move most process destruction earlier.
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 22 Sep 2004 05:42:17 +0000 (05:42 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 22 Sep 2004 05:42:17 +0000 (05:42 +0000)
src/threads/thread.c
src/userprog/pagedir.c
src/userprog/process.c
src/userprog/process.h

index 560423b7de39dd9f3c6d92efda1b4e23ce811b72..eb9646520de0e2b0b2af7c3254451ff5f86eefe1 100644 (file)
@@ -49,7 +49,6 @@ static struct thread *next_thread_to_run (void);
 static void init_thread (struct thread *, const char *name, int priority);
 static bool is_thread (struct thread *);
 static void *alloc_frame (struct thread *, size_t size);
-static void destroy_thread (struct thread *);
 static void schedule (void);
 void schedule_tail (struct thread *prev);
 static tid_t allocate_tid (void);
@@ -198,6 +197,10 @@ thread_exit (void)
 {
   ASSERT (!intr_context ());
 
+#ifdef USERPROG
+  process_exit ();
+#endif
+
   /* Just set our status to dying and schedule another process.
      We will be destroyed during the call to schedule_tail(). */
   intr_disable ();
@@ -333,20 +336,6 @@ next_thread_to_run (void)
     return list_entry (list_pop_front (&ready_list), struct thread, elem);
 }
 
-/* Destroys T, which must not be the running thread. */
-static void
-destroy_thread (struct thread *t) 
-{
-  ASSERT (is_thread (t));
-  ASSERT (t != thread_current ());
-
-#ifdef USERPROG
-  process_destroy (t);
-#endif
-  if (t != initial_thread)
-    palloc_free (t);
-}
-
 /* Completes a thread switch by activating the new thread's page
    tables, and, if the previous thread is dying, destroying it.
 
@@ -374,11 +363,15 @@ schedule_tail (struct thread *prev)
   process_activate ();
 #endif
 
-  /* If the thread we switched from is dying, destroy it.
-     This must happen late because it's not a good idea to
-     e.g. destroy the page table you're currently using. */
+  /* If the thread we switched from is dying, destroy its struct
+     thread.  This must happen late so that thread_exit() doesn't
+     pull out the rug under itself. */
   if (prev != NULL && prev->status == THREAD_DYING) 
-    destroy_thread (prev);
+    {
+      ASSERT (prev != cur);
+      if (prev != initial_thread)
+        palloc_free (prev);
+    }
 }
 
 /* Schedules a new process.  At entry, interrupts must be off and
index 3b634b9592823995689af4bc60ea317a302d47e4..c5c2e5dc44690804c84ebb9f436211fb0e909bc3 100644 (file)
@@ -28,6 +28,7 @@ pagedir_destroy (uint32_t *pd)
   if (pd == NULL)
     return;
 
+  ASSERT (pd != base_page_dir);
   for (pde = pd; pde < pd + pd_no (PHYS_BASE); pde++)
     if (*pde & PG_P) 
       {
index 08e78c683e0024af747573e9fb78e48d63aee4e2..5b50aa53a199e64001302574428091436809aaf8 100644 (file)
@@ -82,17 +82,24 @@ execute_thread (void *filename_)
   NOT_REACHED ();
 }
 
-/* Destroys the user address space in T and frees all of its
-   resources. */
+/* Free the current process's resources. */
 void
-process_destroy (struct thread *t)
+process_exit (void)
 {
-  ASSERT (t != thread_current ());
-
-  if (t->pagedir != NULL) 
+  struct thread *cur = thread_current ();
+  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. */
+  pd = cur->pagedir;
+  if (pd != NULL) 
     {
-      pagedir_destroy (t->pagedir);
-      t->pagedir = NULL; 
+      cur->pagedir = NULL;
+      pagedir_activate (NULL);
+      pagedir_destroy (pd);
     }
 }
 
@@ -103,10 +110,11 @@ process_activate (void)
 {
   struct thread *t = thread_current ();
 
-  /* Activate T's page tables. */
+  /* Activate thread's page tables. */
   pagedir_activate (t->pagedir);
 
-  /* Set T's kernel stack for use in processing interrupts. */
+  /* Set thread's kernel stack for use in processing
+     interrupts. */
   tss_set_esp0 ((uint8_t *) t + PGSIZE);
 }
 \f
index cd9463d6928c4fdd8fadbb52d0abd9ddad9472ef..2db1021af323b9acd6c6502c40579072d7454d15 100644 (file)
@@ -4,7 +4,7 @@
 #include "threads/thread.h"
 
 tid_t process_execute (const char *filename);
-void process_destroy (struct thread *);
+void process_exit (void);
 void process_activate (void);
 
 #endif /* userprog/process.h */