From: Ben Pfaff Date: Wed, 22 Sep 2004 05:42:17 +0000 (+0000) Subject: Move most process destruction earlier. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35d96421c3bdd3911dc679918ae3d81ab7479797;p=pintos-anon Move most process destruction earlier. --- diff --git a/src/threads/thread.c b/src/threads/thread.c index 560423b..eb96465 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -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 diff --git a/src/userprog/pagedir.c b/src/userprog/pagedir.c index 3b634b9..c5c2e5d 100644 --- a/src/userprog/pagedir.c +++ b/src/userprog/pagedir.c @@ -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) { diff --git a/src/userprog/process.c b/src/userprog/process.c index 08e78c6..5b50aa5 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -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); } diff --git a/src/userprog/process.h b/src/userprog/process.h index cd9463d..2db1021 100644 --- a/src/userprog/process.h +++ b/src/userprog/process.h @@ -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 */