Don't destroy current thread's pagedir before activating a different
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 2 Sep 2004 21:03:03 +0000 (21:03 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 2 Sep 2004 21:03:03 +0000 (21:03 +0000)
one (!).
thread_wake() needs to run with interrupts off.

src/threads/synch.c
src/threads/thread.c
src/threads/thread.h
src/userprog/addrspace.c

index ea38068ad017f58888cdf34c9d9f5ce652d4449e..08ba8f4b90cff42b698ab89a99f7c19d65ba45f6 100644 (file)
@@ -51,7 +51,7 @@ sema_down (struct semaphore *sema)
       struct thread_elem te;
       te.thread = thread_current ();
       list_push_back (&sema->waiters, &te.elem);
-      thread_sleep ();
+      thread_block ();
     }
   sema->value--;
   intr_set_level (old_level);
@@ -70,8 +70,8 @@ sema_up (struct semaphore *sema)
 
   old_level = intr_disable ();
   if (!list_empty (&sema->waiters)) 
-    thread_wake (list_entry (list_pop_front (&sema->waiters),
-                             struct thread_elem, elem)->thread);
+    thread_unblock (list_entry (list_pop_front (&sema->waiters),
+                                struct thread_elem, elem)->thread);
   sema->value++;
   intr_set_level (old_level);
 }
index 7b34722777e6ae1beb14cb4b44cc23b633064a7a..2694a10959ba9ccd9965f498197ec5add8905a5f 100644 (file)
@@ -113,7 +113,7 @@ thread_create (const char *name, thread_func *function, void *aux)
   sf->eip = switch_entry;
 
   /* Add to run queue. */
-  thread_wake (t);
+  thread_unblock (t);
 
   return t;
 }
@@ -160,25 +160,29 @@ thread_execute (const char *filename)
   sf->eip = switch_entry;
 
   /* Add to run queue. */
-  thread_wake (t);
+  thread_unblock (t);
 
   return true;
 }
 #endif
 
-/* Transitions T from its current state to THREAD_READY, the
-   ready-to-run state.  On entry, T must be ready or blocked.
+/* Transitions a blocked thread T from its current state to the
+   ready-to-run state.  If T is not blocked, there is no effect.
    (Use thread_yield() to make the running thread ready.) */
 void
-thread_wake (struct thread *t) 
+thread_unblock (struct thread *t) 
 {
+  enum intr_level old_level;
+
   ASSERT (is_thread (t));
-  ASSERT (t->status == THREAD_READY || t->status == THREAD_BLOCKED);
-  if (t->status != THREAD_READY) 
+
+  old_level = intr_disable ();
+  if (t->status == THREAD_BLOCKED) 
     {
       list_push_back (&run_queue, &t->rq_elem);
       t->status = THREAD_READY;
     }
+  intr_set_level (old_level);
 }
 
 /* Returns the name of thread T. */
@@ -238,9 +242,9 @@ thread_yield (void)
 }
 
 /* Puts the current thread to sleep.  It will not be scheduled
-   again until awoken by thread_wake(). */
+   again until awoken by thread_unblock(). */
 void
-thread_sleep (void) 
+thread_block (void) 
 {
   ASSERT (!intr_context ());
   ASSERT (intr_get_level () == INTR_OFF);
@@ -261,7 +265,7 @@ idle (void *aux UNUSED)
 
       /* Let someone else run. */
       intr_disable ();
-      thread_sleep ();
+      thread_block ();
       intr_enable ();
     }
 }
@@ -388,12 +392,13 @@ schedule_tail (struct thread *prev)
   ASSERT (intr_get_level () == INTR_OFF);
 
   cur->status = THREAD_RUNNING;
-  if (prev != NULL && prev->status == THREAD_DYING) 
-    destroy_thread (prev);
 
 #ifdef USERPROG
   addrspace_activate (cur);
 #endif
+
+  if (prev != NULL && prev->status == THREAD_DYING) 
+    destroy_thread (prev);
 }
 
 /* Schedules a new process.  At entry, interrupts must be off and
index aab1a73902410757eac49b628ecf2e58670bc978..e8927def25ebc99594a541425096ddc6eff8c4e4 100644 (file)
@@ -43,12 +43,12 @@ struct thread *thread_create (const char *name, thread_func *, void *);
 bool thread_execute (const char *filename);
 #endif
 
-void thread_wake (struct thread *);
+void thread_unblock (struct thread *);
 const char *thread_name (struct thread *);
 
 struct thread *thread_current (void);
 void thread_exit (void) NO_RETURN;
 void thread_yield (void);
-void thread_sleep (void);
+void thread_block (void);
 
 #endif /* thread.h */
index 1170f16ab92a7f61f1a93ad381ea49ff38208e63..e8d8305d7efb1c4a0943812a39540e5ba3f78a49 100644 (file)
@@ -273,7 +273,6 @@ addrspace_activate (struct thread *t)
 {
   ASSERT (t != NULL);
   
-  if (t->pagedir != NULL)
-    pagedir_activate (t->pagedir);
+  pagedir_activate (t->pagedir);
   tss_set_esp0 ((uint8_t *) t + PGSIZE);
 }